03-11-2009 12:25 PM - edited 03-11-2009 12:26 PM
Hello,
I try to resize an array of LStrHandles within a shared library. Here the C-code - attached a picture of the calling SubVI:
/* Call Library source file */
#include <stdio.h>
#include "extcode.h"
/* Typedefs */
typedef struct {
long dimSize;
LStrHandle elt[1];
} TD1;
typedef TD1 **TD1Hdl;
long strArray(TD1Hdl arg1);
long strArray(TD1Hdl arg1)
{
long err=0, count=2;
err = DSSetHandleSize((UHandle)arg1, sizeof(long) + count*sizeof(LStrHandle));
if(err) {
printf("ERROR: 'DSSetHandleSize()': %ld\n", err);
return err;
};
(*arg1)->dimSize = (*arg1)->dimSize;
return noErr;
}
I know there are a lot of threads, I read some and also tried the provided source code but somehow LabVIEW crashes. I don't know if it is valueable but when I change the following line it does not crash:
(*arg1)->dimSize = (*arg1)->dimSize;
Thanks for any help,
Johannes
OS: RedHat
LV: 8.2 Prof
Solved! Go to Solution.
03-11-2009 02:36 PM - edited 03-11-2009 02:40 PM
To be honest I'm not fully sure why that would crash but proper dealing is a lot more complicated than what you have done. The crash probably happens not in the C fucntion but on return of the function as LabVIEW tries to display the data. DSSetHandleSize() does not initialize the area it allocates additionally so there is likely garbage which LabVIEW then tries to interpret as string handles and consequently crashes.
You should also use NumericArrayResize() whenever possible as it takes care of various complications that can be hard to deal with on multi platform programs. NumericArrayResize() does use internally DSSetHSzClr() which initializes additional memory to 0. That would avoid the crash since LabVIEW does interpret NULL handles as the default for the according datatype, which would be here an empty string.
#include "extcode.h"
#if IsOpSystem64Bit
#define uPtr uQ
#else
#define uPtr uL
#endif
typedef struct {
int32 dimSize;
LStrHandle elm[1];
} TDStrArr, **TDStrArrHdl;
MgErr MyArrayFunc(TDStrArrHdl arr)
{
int32 count = 4;
LStrHandle p;
MgErr err = noErr;
/* The array could be non empty so dispose of any elements in it that are bigger than what we need */
for (i = (*arr)->dimSize - 1; i >= count; i--)
{
p = (*arr)->elm[i];
if (p)
DSDisposeHandle(p)
}
(*arr)->dimSize = i + 1;
/* resize the array handle to get enough space */
err = NumericArrayResize(uPtr, 1, (UHandle*)&arr, count);
if (err)
return err;
/* Fill in the data as desired */
for (i = 0; !err && i < count; i++)
{
p = (*arr)->elm[i];
#if !complicated
err = NumericArrayResize(uB, 1, (UHandle*)&p, 1);
#else
if (p)
{
err = DSSetHSzClr(p, sizeof(int32));
}
else
{
p = DSNewHClr(sizeof(int32));
if (p)
(*arr)->elm[i] = p;
else
err = mFullErr;
}
#endif
if (!err)
err = LStrPrintf(p, "%ld", i);
}
(*arr)->dimSize = i;
return err;
}
Rolf Kalbermatter
03-11-2009 03:51 PM
You were right - not the C-function crashed but LabVIEW when the C-function returned. 'NumericArrayResize' was the answer. I tried 'SetCINArraySize' before but this caused a crash in the C-function immediately. I used the same C-code in a Code Interface Node and there 'SetCINArraySize' worked very well.
I thought 'NumericArrayResize' should only be used to resize "numeric" arrays but I assume as a string array is also based on a numeric array 'NumericArrayResize' is working for string arrays as well.
Thank you very much.
Johannes
09-29-2011 06:49 AM - edited 09-29-2011 06:52 AM
You made my day! Thanks a lot!!!