LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

LabVIEW MoveBlock and getting a string from a DLL (allocated by the DLL)

Solved!
Go to solution

Hello fellow LabVIEW addicts,

 

I have a little question concerning the LabVIEW MoveBlock function. 

For a project I need to use an external DLL that needs to be called by my LabVIEW program. 

The DLL essentially returns a void * to a buffer and the size of the buffer (size_t). This buffer is just string data being returned by the DLL. The DLL allocates this data and later on in the program I need to pass this pointer to a second function from the DLL to explicitely let the DLL know that I'm done using the data so it can deallocate that data. 

 

Here is the documentation of the function I want to use: 

 

int rt_receive (void* buffer, size_t length);

 

To deallocate the memory I need to call: 

 

int rt_free (void* buffer);

 

I was trying to get this information into a LabVIEW string by invoking the LabVIEW MoveBlock function. 

 

I configured the LabVIEW MoveBlock Call Library Function Node according to document: 

Dereferencing Pointers from C/C++ DLLs in LabVIEW

 

After several attempts to move this data to a LabVIEW string (and crashing LabVIEW all the time) I made the switch from the MoveBlock function to the GetValueByPointer VI. 

With the GetValueByPointer VI everything works as expected and I get the string in LabVIEW just as expected!

 

Attached to this mail there is a png file that shows the working solution (GetValueByPointer VI) and the not working solution (LabVIEW MoveBlock Call Library Function Node).

 

However, it keeps bugging me that I cannot get the LabVIEW MoveBlock function to work. I want to understand what I'm doing wrong...

 

I tried several other things with the MoveBlock function. Like allocating a U8 array that can hold the size returned by the DLL and passing that array to the MoveBlock function. Same result - crash of LabVIEW.

Passing a LabVIEW string that already contains enough characters to hold the data to the MoveBlock function - same result - crash of LabVIEW. 

 

Does anyone have an idea what I'm doing wrong with the MoveBlock function? (how to copy the string data from the DLL to a LabVIEW string) 

 

Note: The DLL returns a 32 bit pointer. The DLL is 32 bit and I'm using LabVIEW 2014 32 bit on Win 7 Prof 64 bit. I cannot supply the DLL (license issue) but will try to create one myself with Visual Studio to see if I can reproduce the problem with my own DLL. (although I'm not so good in C++ anymore)

 

Thanks for all the help or suggestions!

Kirsten

 

working and non working code.png

 

 

0 Kudos
Message 1 of 6
(5,186 Views)
Solution
Accepted by topic author k_tunsten

Since you say the XNode works then you are dealing with a pointer and not a handle (pointer to a pointer), therefore you should be passing the address to MoveBlock by value and not as a pointer to a value.

Message 2 of 6
(5,177 Views)
Solution
Accepted by topic author k_tunsten

We can't see the full configuration of the Call Library Function Node and you didn't attach your VIs, so I can't say these are the only problems, but definitely one problem is that you pass the source address by pointer rather than by value, and another likely problem is that you don't preallocate the destination string.

 

The value on the wire coming from the Pointer terminal is a memory address - a pointer - so it should be passed by value. You have that parameter configured to be passed by pointer, which means you're passing a pointer to a pointer - you're passing the address where the address is stored, rather than the address where the string is stored.

 

You should preallocate the destination string. The easiest way to do this is to initialize an array of U8 of the correct size, then use Byte Array to String to turn it into a string.

0 Kudos
Message 3 of 6
(5,176 Views)
Solution
Accepted by topic author k_tunsten

Thanks Darin.K and nathand!

 

This was one of the changes I already tried but with no luck, it kept crashing on me. But, you are both completely right that the value should be passed and not the pointer to value. 

In order for the MoveBlock to work it seems that I also had to change the Destination parameter.

Previously I had set it to "Adapt to type" and the default is then "Handles to Value" but this did not work.

By changing the type to string and the String format to C String Pointer it worked.

 Another way for the MoveBlock function to work is that I keep the Type set to "Adapt to Type" but the Data format set to "Array Data Pointer" since string essentially just are arrays of characters. 

 

A big thanks to both of you for pointing me in the correct direction!

 

Message 4 of 6
(5,138 Views)
Solution
Accepted by topic author k_tunsten

One extra check though. As Nathan already mentioned you do need to allocate the destination buffer BEFORE calling the function. Have you done the Initiliaze Array for an U8 array with the same size that you pass to the Size parameter of your MoveBlock() call, then convert that byte array to a string and wire it to the left side of the destination terminal?

 

Otherwise you let the function write into undefined memory, which can crash, cause an 1097 error or seemingly work but cause pretty nasty problems later on in your app.

If you configure it as a String, passed as C String Pointer, you can also let LabVIEW do the preallocation by also specifying the Minimum Size in the Call Library Node configuration for the Destination parameter to use the value passed in in the the Size parameter. 

Rolf Kalbermatter
My Blog
0 Kudos
Message 5 of 6
(5,114 Views)

Thanks for the reminder Rolf!

Yes I did allocate memory before calling the function via the  Initiliaze Array [U8] or via the Size parameter. 

Anyway, I forgot to mention it in my reply and you're completely right - this is also a very important piece of information that should be mentioned here for all others running into the same problem and reading this thread!

 

Thanks for all the help!

Kirsten

0 Kudos
Message 6 of 6
(5,109 Views)