LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Returning a pointer to unsigned char from DLL call

I used Import shared DLL to create a LV wrapper for my dll. One of the functions returns a buffer of unsigned chars. It is declared as * unsigned char. LV translated this call to return a string. The buffer returns usually 8 bytes and some of them are zeros. I am only getting bytes up to the first 0. So instead of 8 bytes I get 3 if the fourth byte is 0.

In order to fix this I went into the function node and manually changed it to a pointer to a numeric array of unsigned char. In my opinion this should be the equivalent to * unsigned char. Now I get run time error saying that ActiveX running my function crashed.

Any ideas most welcome

Thanks

CT

0 Kudos
Message 1 of 11
(5,985 Views)

Can you share your code?  I'm confused about the ActiveX/DLL part.  Where does ActiveX come into this question?  I'm also not clear how you configured the Call Library Function Node.  You should be changing the parameter to an array, not to a pointer to an array.

0 Kudos
Message 2 of 11
(5,977 Views)

@Cimteker wrote:

I used Import shared DLL to create a LV wrapper for my dll. One of the functions returns a buffer of unsigned chars. It is declared as * unsigned char. LV translated this call to return a string. The buffer returns usually 8 bytes and some of them are zeros. I am only getting bytes up to the first 0. So instead of 8 bytes I get 3 if the fourth byte is 0.

In order to fix this I went into the function node and manually changed it to a pointer to a numeric array of unsigned char. In my opinion this should be the equivalent to * unsigned char. Now I get run time error saying that ActiveX running my function crashed.

Any ideas most welcome

Thanks

CT


Is this function returning an unsigned char array as function return value or through a parameter?

In the first case you can not simply change it into an array of unsigned bytes. In the second case configuring the parameter to to be an array of unsigned 8-Bit values AND passing it as C array pointer AND making sure you allocate a big enough array in the LabVIEW diagram (for instance by using Initialize Array) so the function has some memory to write its data into, should make it work.

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

Thank you for your responses.

 

This is the prototype of this function from its header file:

 

long __stdcall CANcardXL_receive(IN long vi, IN unsigned char objHandler, IN unsigned char maxLen, OUT unsigned char * data, OUT unsigned char * len);

 

The image shows how LV setup the node for it.

 

In C this function returns a pointer to unsigned char. So I allocate a buffer and pass a pointer to it. It also assigns the length of data received to len. The issue is that unsigned char is NOT string. Unsigned char is typically used for binary data (as it is also defined as BYTE in WIN32 convention). 

 

I hope that clears my question.

Thanks

CT

 

 

 

0 Kudos
Message 4 of 11
(5,954 Views)

Hi Nathan,

 

Yes, you are right, The actual error messsage I am getting is: (when I manually configure the node to return an array of unsigned char)

 

Call Library Function Node in CANcardXL_32.lvlib:CANcard XL receive.vi

LabVIEW:  An exception occurred within the external code called by a Call Library Function Node. The exception might have corrupted the LabVIEW memory. Save any work to a new location and restart LabVIEW.

 

Thanks

Jerry

 

0 Kudos
Message 5 of 11
(5,947 Views)

It would have been more helpful to provide an image showing how your are calling the DLL after changing it to an array, including the configuration of the Call Library Function Node (the dialog box that pops up where you configure the individual parameters).  The image you showed says nothing about the error you described.

 

You should change the data parameter to an array of U8.  The array must be initialized to maxLen elements (using Initialize Array) prior to calling the function.  The "len" parameter should be a scalar U8 (NOT an array or string), passed by pointer.

0 Kudos
Message 6 of 11
(5,940 Views)

Here it is

Thanks

CT

0 Kudos
Message 7 of 11
(5,936 Views)

Can you please explain how I can initialize this array? This is an output from the VI that will go to my Locals.BinArray which is defined as an array of 255 integers.

 

Thanks

CT

0 Kudos
Message 8 of 11
(5,933 Views)

Again, you just need to use the "Initialize Array" function to create an array of maxLen U8 elements, and wire that to the input side of the "data" parameter in the call library function node.  The output side will have the data you want.

 

EDIT: your comment about "Locals.BinArray" makes me wonder about your overall architecture; are you overusing local variables?

0 Kudos
Message 9 of 11
(5,921 Views)

@Cimteker wrote:

Can you please explain how I can initialize this array? This is an output from the VI that will go to my Locals.BinArray which is defined as an array of 255 integers.

 

Thanks

CT


Well the buffer as such is an input to the function, but the function fills in information. There is no way a function could return a buffer through a single pointer parameter. For that to work the pointer would need to be passed by reference as char **variable, but a parameter declared as such is not necessarily a pointer that is returned by the function, it could also be a array of pointers, or a handle, or a few other things.

 

C is very unspecific about pointers: char *variable as function parameter can mean an array passed by value but also a single skalar byte passed by reference. C++ allows a little more specific syntax where array parameters CAN be declared as char variable[] (but don't have to!).

 

In any case if you call a function that accepts an array as a single pointer, you always have to provide the memory area for that array in the caller (and for buffers the function is supposed to write into, and it's not a fixed size buffer by contract of the function documentation, it should also accept a second parameter that tells it how large the buffer is in order that it does not write over the end of the buffer).

 

As Nathand already explained. the easiest way in LabVIEW to make sure you have an array of a specific size is to use the Initialize Array node.

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