Jump to content

Calling a function from a dll with a pointer to a complex struct


Recommended Posts

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

post-5002-0-85015700-1385148023.png

Link to comment

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.

Link to comment

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.

Link to comment
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 

Link to comment
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?

Link to comment
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

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