russellb78 Posted November 22, 2013 Report Posted November 22, 2013 Hello, I am trying to call a function from a dll with a pointer to a complex struct. I have tried multiple ways to represent the string in the struct (see attached typedefs), but the output clusters from the dll call always has the same values as input (i.e the dll isn't updating the output values). The ref ptr is based on an example from this link and I have attached a screenshot of my code for this case: https://decibel.ni.com/content/docs/DOC-9079 Here is how the vendor defines the struct: typedef struct { dword passkey; //password dword request; //0=readprop, 1=writeprop, 2=writerelinquish dword deviceid; //device instance dword objectid; //objectid dword propid; //property id dword arrindex; //array index dword datatype; //see simpletypes dword value; dword errorclass; dword errorcode; dword priority; //1..16 union { char sval[1500]; wchar_t wval[1500/2]; byte bval[1500]; BACnetDate dval; BACnetTime tval; datetime dtval; directaddr da; HWND listbox; bufptr buf; Range rg; bdrCOV cov; pxfer *px; }aux; } bdrbag; Here is how the vendor defines the struct in their vb example: Type bdrbag passkey As Long 'password request As Long '0=readprop, 1=writeprop, 2=writeproprelinquish deviceid As Long 'device instance ObjectID As Long 'objectid propid As Long 'property id arrindex As Long 'array index datatype As Long 'see simpletypes value As Single errorclass As Long errorcode As Long priority As Long '1..16 sval(0 To 127) As Byte 'string value End Type Thanks, Russell TYPEDEF_BACNET_bdrbag_byte_cluster.ctl TYPEDEF_BACNET_bdrbag.ctl TYPEDEF_BACNET_bdrbag_ref_ptr.ctl Quote
candidus Posted November 22, 2013 Report Posted November 22, 2013 First thing that comes into my mind: struct alignment. LV clusters are byte aligned, the default alignment when working with Visual C++ is 8 bytes. Your DLL vendor probably didn't change that, so you might need dummy elements in your cluster to ensure every data member starts at a multiple of 8 bytes. Quote
Rolf Kalbermatter Posted November 22, 2013 Report Posted November 22, 2013 Well the sval is not a pointer but a fixed size string or byte array and as such must be inlined in the structure. Your bdrbag_byte_cluster.ctl is as such the most accurate control to use. However it only matches the Visual Basic definition not the original C definition as in there it is really 1500 bytes long, not just 127. As long as you are sure that the underlying function is not trying to write past byte 127 there won't be a problem though. All the other typedefs are not suited to resemble the C structure declaration in any way. And candidus, alignment is not an issue for this particular structure. The alignment rule specifies that each structure element is aligned on the smaller value of either the integral element size or the alignment value. Here all numerics are 32 bit sized and align therefore automatically on their natural position and the string has an integral size of 1 byte and has therefore no alignment requirement. Quote
russellb78 Posted November 22, 2013 Author Report Posted November 22, 2013 Well the sval is not a pointer but a fixed size string or byte array and as such must be inlined in the structure. Your bdrbag_byte_cluster.ctl is as such the most accurate control to use. However it only matches the Visual Basic definition not the original C definition as in there it is really 1500 bytes long, not just 127. As long as you are sure that the underlying function is not trying to write past byte 127 there won't be a problem though.All the other typedefs are not suited to resemble the C structure declaration in any way. And candidus, alignment is not an issue for this particular structure. The alignment rule specifies that each structure element is aligned on the smaller value of either the integral element size or the alignment value. Here all numerics are 32 bit sized and align therefore automatically on their natural position and the string has an integral size of 1 byte and has therefore no alignment requirement. Thanks Rolf, I was thinking that cluster option was the most acccurate option, but it doesn't seem to return an updated value so there must be something else wrong with the dll or my interpretation of the struct. I did have 1500 elements before, but seemed to make editing the cluster and VI in LV very slow and also caused the dll to error out at times. Thanks, Russell Quote
Rolf Kalbermatter Posted November 22, 2013 Report Posted November 22, 2013 Thanks Rolf, I was thinking that cluster option was the most acccurate option, but it doesn't seem to return an updated value so there must be something else wrong with the dll or my interpretation of the struct. I did have 1500 elements before, but seemed to make editing the cluster and VI in LV very slow and also caused the dll to error out at times. Thanks, Russell Well, it is quite possible that the first section of the structure needs to be filled in with specific values that tell the function what to return in the union and for what resource (device, subunit, or whatever). So having even one value off might simply cause the function to error out. Have you checked the function return value itself to not indicate some error condition? Quote
russellb78 Posted November 22, 2013 Author Report Posted November 22, 2013 Well, it is quite possible that the first section of the structure needs to be filled in with specific values that tell the function what to return in the union and for what resource (device, subunit, or whatever). So having even one value off might simply cause the function to error out. Have you checked the function return value itself to not indicate some error condition? Rolf, I do sometimes get an error from the return value (which the vendor said happens at times). He suggested retrying until the return value is zero (i.e no error). When I do get a zero return value the output cluster has the same values as the input cluster (i.e the incorrect output values). In terms of filling the specific values in the function I have copied the same input values that are used in the vendor's VB example executable. The VB example executable executes properly, after several retries of course, and returns the output values I would expect. So I can't tell what I am doing differently from the VB code. I have web meeting with one of the vendor's support engineers on Monday so he can see exactly what is happening on my computer and hopefully determine what might be wrong. Unfortunately he doesn't have LV at his site and isn't familiar so he can't test it at his site. Thanks again, Russell Quote
russellb78 Posted November 26, 2013 Author Report Posted November 26, 2013 I spoke to the vendor this afternoon and it turns out there is an additional function that has to be called in order to get the results (i.e. correct output values). So it appears to be working now. Thanks for the help, Russell Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.