Jump to content
Developer Wiki and Function Reference Links ×

Using dynarray of char as a variable parameter


Recommended Posts

Has anyone else had a problem using a dynarray of char as a variable parameter in a user defined function?

What I am seeing in my script is the contents of the array disappear as soon as the procedure returns. If I change the type of the variable parameters to STRING, it works just fine. Scoping the function inside the calling function doesn't help, and I don't think it is an ALLOCATE problem because the dynarrays hold values just fine inside the function.

Here's the function followed by the function that is calling it FWIW... (Sorry about the lack of tabbing...)

{************************************************************}

FUNCTION LibHasIDLabel(theObj: HANDLE; VAR theRecordName, theIDLabel: DYNARRAY[] OF CHAR): BOOLEAN;

VAR

recHand: HANDLE;

recIndex, fieldIndex: INTEGER;

recName, fieldName: STRING;

labelFound: BOOLEAN;

BEGIN

LibHasIDLabel := FALSE;

labelFound := FALSE;

recIndex := 1;

WHILE ((recIndex <= NumRecords(theObj)) AND (NOT labelFound)) DO

BEGIN

recHand:= GetRecord(theObj, recIndex);

recName:= GetName(recHand);

fieldIndex := 1;

WHILE ((fieldIndex <= NumFields(recHand)) AND (NOT labelFound)) DO

BEGIN

fieldName := GetFldName(recHand, fieldIndex);

IF ((Pos('IDLabel', fieldName)) = 1) THEN

BEGIN

theRecordName := recName;

theIDLabel := GetRField(theObj, recName, fieldName);

LibHasIDLabel := TRUE;

labelFound := TRUE;

{DBGINFO}

Message('IDLabel ', theIDLabel, ' found in record ', theRecordName);

Wait(2);

{\DBGINFO}

END; {IF Pos}

fieldIndex := fieldIndex + 1;

END; {WHILE fieldIndex}

recIndex := recIndex + 1;

END; {WHILE recIndex}

END; {Lib_HasIDLabel}

{************************************************************}

FUNCTION CopyOver(theDestPIO: HANDLE): BOOLEAN;

VAR

parent, newObj, tempGroup: HANDLE;

destPIOType, srcPIORecName, destPIORecName, srcPIOIDLabel, destPIOIDLabel: DYNARRAY[] OF CHAR;

index: INTEGER;

BEGIN

IF (GetType(theDestPIO) = OBJ_PIO) THEN

BEGIN

{Make sure the two plug-ins are of the same type}

destPIOType := LibGetPIOType(theDestPIO);

{DBGINFO}

Message('Destination PIO of type ', destPIOType, ' picked');

Wait(1);

{\DBGINFO}

IF (Pos(srcPIOType, destPIOType) = 1) THEN

BEGIN

{Copy the IDLabel of theDestPIO to the srcPIO so that it is retained}

IF (LibHasIDLabel(theDestPIO, destPIORecName, destPIOIDLabel)) AND (LibHasIDLabel(srcPIO, srcPIORecName, srcPIOIDLabel)) THEN

BEGIN

SetRField(srcPIO, srcPIORecName, 'IDLabel', destPIOIDLabel);

{DBGINFO}

Message('IDLabel ', destPIOIDLabel, ' copied to source PIO Record ', srcPIORecName);

Wait(3);

{\DBGINFO}

END; {IF LibHasIDLabel}

{Strip the non PIO records from theDestPIO}

index := 1;

WHILE ( index < NumRecords(theDestPIO)) DO

BEGIN

{DBGINFO}

Message('Deleting record ', index, ' from destPIO');

Wait(1);

{\DBGINFO}

DelObject(GetRecord(theDestPIO, index));

index := index + 1;

END; {WHILE index}

{Add any extra records that the srcPIO has}

index := 1;

WHILE ( index < NumRecords(srcPIO)) DO

BEGIN

{DBGINFO}

Message('Copying record ', index, ' from sourcePIO');

Wait(1);

{\DBGINFO}

LibCopyNewRec(srcPIO, theDestPIO, GetName(GetRecord(srcPIO, index)));

index := index + 1;

END; {WHILE index}

{Copy the PIO Record}

{DBGINFO}

Message('Copying the PIO Record');

Wait(1);

{\DBGINFO}

LibCopyExistRec(srcPIO, theDestPIO, destPIOType);

{Reset the dest object so that the changes are reflected}

ResetObject(theDestPIO);

END; {IF Pos}

END; {IF GetType}

CopyOver := FALSE;

END; {CopyOver}

Link to comment

I've never used dynarray so maybe you can teach me something. Where is ALLOCATE happening? I would've thought you'd need that in the second function after you declare them and before you assign to them.

(does sound like a scope problem of some kind)

edit: and while we're at it, why is dynarray of char preferable to string?

Edited by ccroft
Link to comment
the contents of the array disappear as soon as the procedure returns.

Do you mean when CopyOver returns, or when LibHasIDLabel returns, or the whole PIO procedure?

If you mean CopyOver, I think Charles is right, it is a problem of the variables' scope. Each time you leave the function CopyOver, you should expect all your locally declared variable data to be invalid. The fact that Stings don't is an abnormality, not the norm. To get the values to stick each time you enter CopyOver, declare the following as global variables and not local:

gdestPIOType, gsrcPIORecName, gdestPIORecName, gsrcPIOIDLabel, gdestPIOIDLabel: DYNARRAY[] OF CHAR;

You can use the global variables locally, but I would add them to the calling chain to keep it neat and tidy, as:

FUNCTION CopyOver (theDestPIO: HANDLE; VAR destPIOType, srcPIORecName, destPIORecName, srcPIOIDLabel, destPIOIDLabel: DYNARRAY[] OF CHAR): BOOLEAN;

As for allocating variable space before it is used it, I always do, except when reading from files. If your first assignment allocates what you need, you should not expect to be able to add more to a text variable unless you allocate additional space for it. You can always shorten the character data, though. If your data is shorter than 255 characters, why not use Strings and forget about all the hassles of allocation.

Raymond

Link to comment

Your function declarations are as follows:

FUNCTION LibHasIDLabel(theObj: HANDLE; VAR theRecordName, theIDLabel: DYNARRAY[] OF CHAR): BOOLEAN;

FUNCTION CopyOver(theDestPIO: HANDLE): BOOLEAN;

And your calling line:

IF (LibHasIDLabel(theDestPIO, destPIORecName, destPIOIDLabel)) AND (LibHasIDLabel(srcPIO, srcPIORecName, srcPIOIDLabel)) THEN...

When your function LibHasIDLabel completes, it returns a pointer to variable space that was local to LibHasIDLabel; space that disappears the moment you leave LibHasIDLabel. The equivalent space has not been reserved in CopyOver since you never allocated it, so there's no place for the answers to reside when you return. You must ALLOCATE space for your DynArrays before they can be used.

Try:

ChrCnt := 94; { or whatever size your array of Chars needs to be. }

ALLOCATE destPIORecName[1..ChrCnt];

ALLOCATE destPIOIDLabel[1..ChrCnt];

ALLOCATE srcPIORecName[1..ChrCnt];

ALLOCATE srcPIOIDLabel[1..ChrCnt];

IF (LibHasIDLabel(theDestPIO, destPIORecName, destPIOIDLabel)) AND (LibHasIDLabel(srcPIO, srcPIORecName, srcPIOIDLabel)) THEN...

Now, when LibHasIDLabel returns, your data has something to come home to. Of course, ChrCnt can have a different value for each variable, if your needs require it.

HTH,

Raymond

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...