From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Does LV8.2 support this kind of parameter passing between LV and DLL.

I am trying to use "Call Library Function Node" to call a DLL to control a device.
The prototype of one function in the DLL is:  function putcommand(prec: pointer):longint;
The mannual describes the function as following:
 
"Together with the Putcommand function ,a 32 bit pointer, which points to command
message structur (see below) is to be transferred to the DLL."
 
TCommandMsg = packed record
                     ApId : longint;
                     commandnr : word;
                     command : tcommand;
              end;
where the  "tcommand" structure is shown below:
tcommand = packed record
                  commandID : word;
                  param : tparam;
           end;
 
Both the type and size of the fields within the two structures are given.
 
How can I pass the parameter from LV to the DLL?
 
Thanks
0 Kudos
Message 1 of 4
(2,639 Views)
To answer the question in this message's Subject:
Yes! - assuming the "tcommand" and "tparam" parameters are not pointers.
One builds an array of bytes representing the "flattened" (AKA "serialized") TCommandMsg structure and configures the CLF to pass an array-pointer.  The DLL receives the pointer and assumes it points to a struct - which it will IF the array has been packed correctly.  To pack the array correctly means knowing exactly how many bytes each parameter requires, and, if passing a numeric, whether the DLL expects the least-significant byte first (Little-Endian) or the MSB first - Big Endian.  When LabVIEW flattens numerics, it arranges the bytes in Big Endian order.
 
here's a list of the data-types shown below, in order
"C" type      LV type  Identifier
longint (I32) ("Apld")
word    (U16) ("commandnr")
word    (U16) ("commanIDr")
?(tparam) (?)   ("param")
 
of what "C" datatype(s) is tparam composed?
 
Cheers.

huangjack wrote:
I am trying to use "Call Library Function Node" to call a DLL to control a device.
The prototype of one function in the DLL is:  function putcommand(prec: pointer):longint;
The mannual describes the function as following:
 
"Together with the Putcommand function ,a 32 bit pointer, which points to command
message structur (see below) is to be transferred to the DLL."
 
TCommandMsg = packed record
                     ApId : longint;
                     commandnr : word;
                     command : tcommand;
              end;
where the  "tcommand" structure is shown below:
tcommand = packed record
                  commandID : word;
                  param : tparam;
           end;
 
Both the type and size of the fields within the two structures are given.
 
How can I pass the parameter from LV to the DLL?
 
Thanks




Message Edited by tbd on 02-17-2008 01:57 PM
"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 2 of 4
(2,625 Views)
Hi,
Thank you for the explaination.
 
The tparam is a case structure.
tparam = packed record
                   case byte of
                         1 : (B1,B2,B3,B4 : byte);
                         2 : (w1,w2 : word);
                         3 : (i1,i2 : smallint);
                         4 : (r1 : single);
                         5 : (l1 : longint);
end;
 
So there is a structure in structure in structure. How can I pack such data into array?
 
Can I list all the parameters with corrsponding types , then pack them into a cluster.
After that, I flatten the cluster and wire to the CLF which has been configured to pass an array-pointer.
 
Do you think it's gonna work or I have not got what you said?
 
Thanks
 
 

tbd wrote:
 
To answer the question in this message's Subject:
Yes! - assuming the "tcommand" and "tparam" parameters are not pointers.
One builds an array of bytes representing the "flattened" (AKA "serialized") TCommandMsg structure and configures the CLF to pass an array-pointer.  The DLL receives the pointer and assumes it points to a struct - which it will IF the array has been packed correctly.  To pack the array correctly means knowing exactly how many bytes each parameter requires, and, if passing a numeric, whether the DLL expects the least-significant byte first (Little-Endian) or the MSB first - Big Endian.  When LabVIEW flattens numerics, it arranges the bytes in Big Endian order.
 
here's a list of the data-types shown below, in order
"C" type      LV type  Identifier
longint (I32) ("Apld")
word    (U16) ("commandnr")
word    (U16) ("commanIDr")
?(tparam) (?)   ("param")
 
of what "C" datatype(s) is tparam composed?
 
Cheers.

huangjack wrote:
I am trying to use "Call Library Function Node" to call a DLL to control a device.
The prototype of one function in the DLL is:  function putcommand(prec: pointer):longint;
The mannual describes the function as following:
 
"Together with the Putcommand function ,a 32 bit pointer, which points to command
message structur (see below) is to be transferred to the DLL."
 
TCommandMsg = packed record
                     ApId : longint;
                     commandnr : word;
                     command : tcommand;
              end;
where the  "tcommand" structure is shown below:
tcommand = packed record
                  commandID : word;
                  param : tparam;
           end;
 
Both the type and size of the fields within the two structures are given.
 
How can I pass the parameter from LV to the DLL?
 
Thanks




Message Edited by tbd on 02-17-2008 01:57 PM
 

I think it woud be a good idea.   (Mahatma Gandhi when asked what he thought of Western civilization)
0 Kudos
Message 3 of 4
(2,609 Views)


The tparam is a case structure.
tparam = packed record
                   case byte of
                         1 : (B1,B2,B3,B4 : byte);
                         2 : (w1,w2 : word);
                         3 : (i1,i2 : smallint);
                         4 : (r1 : single);
                         5 : (l1 : longint);
end;

Great - in that case we just keep appending data-bytes.  There's actually a clean shortcut that can work here.  Instead of explicitly building an array from individual numerics, we can just "serialize" a LabVIEW nested-cluster control.  There's a "hidden" requirement though, the cluster elements must be ordered precisely.  If you right-click on the cluster-border and choose "Reorder Cluster Control" you'll see that each element of a cluster is indexed - and this order must match the order in your "C" type-defs.
 
Warning: I wasn't sure if small int was 1 byte or 2 - I made it one byte.  Note there's also a case to allow big-endian/little-endian byte-swapping.
 
I wouldn't expect all this to work the first-time - there are many details and CLF/DLL calls tend to be very "sensitive" - but. it can work!
 
Cheers! 
"Inside every large program is a small program struggling to get out." (attributed to Tony Hoare)
0 Kudos
Message 4 of 4
(2,604 Views)