Jump to content

Pass pointer to array of structs to dll


Recommended Posts

I've searched on this topic and read the excellent document detailing how to construct a LV cluster to match a complex C struct type.

However, I can't figure out how to construct the data to pass to a dll function that expects a pointer to an array of structs as an input. I am using LV 8.5.

The C struct looks like this:

typedef struct {

char *DeviceName;

char *Manufacturer;

char *SerialNumber;

unsigned int VendorID;

unsigned int ProductID;

int InputReportLen;

int OutputReportLen;

int Interface;

int Collection;

} mdeviceList2;

DeviceName and Manufacturer have a max size of 50, while SerialNumber has a max size of 20.

And the function prototype looks like this:

extern "C" int _stdcall GetList(

unsigned int VendorID,

unsigned int ProductID,

char *Manufacturer,

char *SerialNum,

char *DeviceName,

mdeviceList2 *pList,

int nMaxDevices);

The problem I am having is how to create the *plist argument in LabVIEW.

The attached image shows how I'm calling it now. I am using standard WinAPI convention, because I get an error 1517 with C calling convention. I am using "Adapt to Type" for *plist with "Pointers to Handles" as the data format.

I'd appreciate any input, even if it's "you can't do that without writing a wrapper."

Thanks!

Link to comment

QUOTE(vituning @ Jan 4 2008, 05:43 AM)

I'd appreciate any input, even if it's "you can't do that without writing a wrapper."

Thanks!

This probably doesn't answer your question, but you did say any input.

I don't have a lot of experience calling external code through DLLs so anybody please correct me if I'm way off, but whenever I have had a "char *Input" to a DLL I have just used a string. It has always worked for me. Also, I noticed you initialized your arrays with 51 and 21 elements, but your description says the max is 50 and 20. The Initialize Array vi initializes the array with the number of elements that you wire to the dimension size input. For example, if I wire a 10 to the dimension size input I will get an array with elements indexed 0 to 9 (10 elements).

Link to comment

QUOTE(TobyD @ Jan 4 2008, 11:36 AM)

This probably doesn't answer your question, but you did say any input.

I don't have a lot of experience calling external code through DLLs so anybody please correct me if I'm way off, but whenever I have had a "char *Input" to a DLL I have just used a string. It has always worked for me. Also, I noticed you initialized your arrays with 51 and 21 elements, but your description says the max is 50 and 20. The Initialize Array vi initializes the array with the number of elements that you wire to the dimension size input. For example, if I wire a 10 to the dimension size input I will get an array with elements indexed 0 to 9 (10 elements).

Thanks for the input! The byte array you see me using for that char * input was a futile attempt to get this to work. I also tried it with conventional strings there. I'm almost positive the problem lies with the cluster -> struct conversion. I wired 51, 51 and 21 to the array size for those strings in the struct to allow for the null character in the return string. Again, I'm shooting in the dark here, and think that this is basically impossible to do using the call library function node straight up like this.

That said, I don't need to make this work anymore since the customer has moved on to using a NI product rather than a third-party board. There's a solution for everything :).

Link to comment

QUOTE(vituning @ Jan 4 2008, 11:45 AM)

Thanks for the input! The byte array you see me using for that char * input was a futile attempt to get this to work. I also tried it with conventional strings there. I'm almost positive the problem lies with the cluster -> struct conversion. I wired 51, 51 and 21 to the array size for those strings in the struct to allow for the null character in the return string. Again, I'm shooting in the dark here, and think that this is basically impossible to do using the call library function node straight up like this.

You can't do that in LabVIEW like that. A Byte array (and a string) in LabVIEW is something very different from a C pointer. When you pass such an element to the Call Library Node and configure the parameter as C pointer, LabVIEW will do the translation for you but inside a cluster is something LabVIEW won't do (and in fact can't do without a configuration dialog that would intimidate anyone but the most diehard C freaks).

You would need to treat it as an uInt32 and then do the pointer to array data and vice versa in the LabVIEW diagram with the use of more CallLibraryNodes calling into external functions to copy data in and out. As to this function it is not clear if the caller is supposed to allocated the necessary pointers with the required size or if the function will allocate them. In the first case you would need to call even more external functions to be able to do that, in the second case there would need to be a driver provided function to deallocate those pointers again.

All in all a real pain and this particular API is very unfriendly to callers in general! It's even hard to call in C and simply a pain in any other environment.

Rolf Kalbermatter

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  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...

Important Information

By using this site, you agree to our Terms of Use.