LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

dll memory allocation problem

Solved!
Go to solution

Hi,

I recently got into trouble with a Program that calls a dll which I write in C. The dll uses LabView memory manager functions to allocate and deallocate memory for a Labview String in an ErrorCluster.

I know there have been many posts about this topic, but none seemed to apply exactly to my case.

When starting the vi, everything works fine at first, only when terminating and restarting it, LabView crashes. It seems as if LabView crashes as soon as it tries to deallocate the (modified) memory of th Errorcluster.

 

Starngely it doesn't always crash. The Program mightbe running 2-3 times in a row smoothly and then crash at the third time.

I managed to reproduce the error in a small program. Vi and dll-code are attached.

 

I hope I didn't miss a post that already treats this exact problem.

Thanks for your help/hints

 

Download All
0 Kudos
Message 1 of 7
(5,141 Views)

I'm guessing a bit here, but I do not think it's a good idea to use the pointer manipulation functions on memory blocks that are actually targets of handles.  LabVIEW may track the memory size associated with the handle.  When you reallocate the pointer, LabVIEW has no way to know that it needs to update the record of the handle that points to it, so when it attempts to deallocate the handle it may be releasing the wrong amount of space or the wrong location.  Use DSSetHandleSize to resize the LStrHandle before copying the new string, don't use DSNewPtr and DSDisposePtr.

0 Kudos
Message 2 of 7
(5,122 Views)
Solution
Accepted by topic author kper

There is nothing inherently wrong about modifying String handles passed into a DLL from LabVIEW but you need to confirm to the protocol!

 

There is one very likely potential issues with your C code.

 

Yoou should really make sure to wrap your error cluster definition with

 

#pragma pack(1)

 

#pragma pack()

 

for Windows 32 bit. Otherwise you may end up with alignment issues since LabVIEW for Windows uses byte packing for it's data structures, but your C compiler will likely attempt to align the code and error string on 4 byte boundaries, resulting in your DLL corrupting the actual string handle pointer badly.

 

Besides of that your handling and copying of the Stiring is VERY low level and accordingly error prone.

 

Instead your SetError() function could look more like this:

 

MgErr SetError(LVError *thisError, LVBoolean thisStatus, int32_t thisCode, char *thisSource)
{
    int newsize = StrLen(thisSource);
MgErr err;

//Set Status and Code thisError->status = thisStatus; thisError->code = thisCode; if (thisError->source)
err = DSSetHandleSize(thisError->source, newsize + sizeof(int32));
else
{
thisError->source = DSNewHClr(newsize + sizeof(int32));
if (!thisError->source)
err = mFullErr;
}
if (!err)
{
MoveBlock(thisSource, LStrBuf(*(thisError->source)), newsize);
LStrLen(*(thisError->source)) = newsize;
}
return err;
}

 

and this could be even more simplified:

 

MgErr SetError(LVError *thisError, LVBoolean thisStatus, int32_t thisCode, char *thisSource)
{
    int newsize = StrLen(thisSource);
MgErr err;

//Set Status and Code thisError->status = thisStatus; thisError->code = thisCode; err = NumericArrayResize(uB, 1, &(thisError->source), newsize);
if (!err)
{
MoveBlock(thisSource, LStrBuf(*(thisError->source)), newsize);
LStrLen(*(thisError->source)) = newsize;
}
return err;
}

 

 

 

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
Message 3 of 7
(5,107 Views)

Hello,

thank you for the quick replys.

The Error was, as suggested in the first reply, that one must use the memory functions using the Handle to reallocate the memory.

 

Thanks a lot as well for the suggestions on how I can inprove my code. As I am quite new to C I always find it hard to keep track of all the available functions.

There were still 2 minor type casting problems in the suggested code. The nicely working function I am using now is attached.

 

As a note for anyone reading who doesn't know it yet: Wrapping the struct declaration with

#pragma pack(1)

...

#pragma pack()

is automatically done if you let LabView automatically create the declarations. It is declared in the include files lv_prolog.h and lv_epilog.h that wrap all struct declarations that are automatically created by labview.

 

Thanks a lot for your help and time!

Greetings

 

0 Kudos
Message 4 of 7
(5,092 Views)

I actually omitted the typecast more or less on purpose, writing the code right into the answer, not copying from any existing code. Typecasts are nice to have and useful to suppress compile warnings and eventually errors, but not substantial to the understanding of what is the right code to use, to achieve a specific functionality. I only start to worry about typecasts when I finalize the code to get it compiled and or cleaned up, especially since typecasts can sometimes hide underlaying problems that can be often solved much easier by changing datatypes apropriately.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 5 of 7
(5,084 Views)

You may need to increase your buffer. Instead of usign 5 bytes, increase it to 50 or so

0 Kudos
Message 6 of 7
(5,067 Views)

@Lazyboy wrote:

You may need to increase your buffer. Instead of usign 5 bytes, increase it to 50 or so


You probably wanted to answer to something else. I have no idea where your remark would apply to in this thread.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 7 of 7
(5,055 Views)