LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

call DLL which has user-defined types

Solved!
Go to solution

I am trying to call a function in a DLL which is

int32 system_config(&recCfg, &pulseCfg, errMsg)

 

recCfg is a structure consisting of 3 doubles and 2 integers

and pulseCfg is a structure consisting of just a boolean

 

 

I am not sure how to configure the input parameters for this in Call Library Function.

 

LabVIEW sees it as

void system_config(void)

 

I see only choices of Numeric, Array, String, Waveform, Digital Waveform, Digital Data, ActiveX, Adapt to Type, and Instance Data Pointer for arg1.  It seems that ActiveX would be the one to use?

 

 

 

 

 

0 Kudos
Message 1 of 14
(4,673 Views)

I believe you can not do this.  You will have to make a dll which breaks out the primitives and returns them.  The call library node can only return and receive primitive C types.

0 Kudos
Message 2 of 14
(4,664 Views)

This concept is often called a wrapper.  We have lots of c++ code us object oriented programming but hade to make a wrapper class that only put out primitive data types.  This restriction is not only to labview by the way.  If you wrote c++ code and wanted to use it in say Pascal I believe you would still need the wrapper.

0 Kudos
Message 3 of 14
(4,663 Views)
Solution
Accepted by nyc_(is_out_of_here)

 


@nyc_(is_out_of_here) wrote:

I am trying to call a function in a DLL which is

int32 system_config(&recCfg, &pulseCfg, errMsg)

 

recCfg is a structure consisting of 3 doubles and 2 integers

and pulseCfg is a structure consisting of just a boolean


 

Actually contrary to what James says you can do it in this case. But your line your are showing is unfortunately very unclear since it does not include the actual typedef for your clusters. So I have to go by what you write in prosa which is ... well .. not very detailed.

 

The first is simply a cluster in LabVIEW with 3 double precision floats followed by the 2 integers. You will have to find out yourself what bitsize integer you will need, since you do not show the typedef of the cluster. In order to be able to connect a cluster to a CLN you have to configure that parameter as Adapt to Type. But beware that does not work for clusters containing strings or arrays at all. LabVIEW strings and arrays are a completely different thing than what a C DLL expects. You can configure individual function parameters to be C compatible pointers to arrays and strings and LabVIEW will make sure to do the conversion on each call, but you can not configure the CLN to convert strings and arrays inside a cluster.

 

The second cluster really is equivalent to a simple boolean passed by reference. Since you do not show the actual type of the boolean it is hard to recommend what datatype to use in LabVIEW. Windows BOOL is a 32 bit integer while C++ bool usually is an 8 bit value which would coincide with the 8 bit boolean LabVIEW is using. You can't configure a boolean parameter directly in the CLN so you could either use an accordingly sized integer or create that cluster with one single LabVIEW boolean anyhow (if your bool is a C++ bool and not something else) and do the same as with the previous cluster/structure parameter.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 4 of 14
(4,645 Views)

 


@James G wrote:

This concept is often called a wrapper.  We have lots of c++ code us object oriented programming but hade to make a wrapper class that only put out primitive data types.  This restriction is not only to labview by the way.  If you wrote c++ code and wanted to use it in say Pascal I believe you would still need the wrapper.


 

Actually for C++ object oriented code the wrapper might help to adapt LabVIEW incompatible datatype paramaters but the real reason you always need a wrapper for that is that C++ invokes methods of an object through the method dispatch table in the object. LabVIEW not having any kind of equivalent to a C function pointer simply can't access those object method dispatch tables at all. In order to call them you need to create a wrapper function for each method you want to call and export this function as a standard C function from the resulting wrapper DLL.

 

Creating a C++ compatible Call Library Node variant is unfortunately not an option. For one its configuration dialog would get idiotically complicated so that almost nobody would use it for sure, and for another each C++ compiler likes to make his own binary interface model for its objects so there is simply no way to come up with a generic C++ code interface.

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

The LV help has quite a good example for custom data types and DLLs. Search for "DLL" in the Example Finder and then "Call DLL.vi". It has a bunch of different scenarios, one of these may match your use case.

 

As Rolf mentioned, things get quite a bit trickier if you have data types of undefined length (strings and arrays). If you have simple clusters then it should be quite easy to communicate with your DLL.

 

 

0 Kudos
Message 6 of 14
(4,620 Views)

Now that the big guns are here I am going to step out before I give out more miss information 🙂

 

Thank you for the more detailed and accurate information.  PS.  The examples really were useful, I recommend you check them out.

0 Kudos
Message 7 of 14
(4,603 Views)

@rolfk wrote:

 


@nyc_(is_out_of_here) wrote:

I am trying to call a function in a DLL which is

int32 system_config(&recCfg, &pulseCfg, errMsg)

 

recCfg is a structure consisting of 3 doubles and 2 integers

and pulseCfg is a structure consisting of just a boolean


 

Actually contrary to what James says you can do it in this case. But your line your are showing is unfortunately very unclear since it does not include the actual typedef for your clusters. So I have to go by what you write in prosa which is ... well .. not very detailed.

 

The first is simply a cluster in LabVIEW with 3 double precision floats followed by the 2 integers. You will have to find out yourself what bitsize integer you will need, since you do not show the typedef of the cluster. In order to be able to connect a cluster to a CLN you have to configure that parameter as Adapt to Type. But beware that does not work for clusters containing strings or arrays at all. LabVIEW strings and arrays are a completely different thing than what a C DLL expects. You can configure individual function parameters to be C compatible pointers to arrays and strings and LabVIEW will make sure to do the conversion on each call, but you can not configure the CLN to convert strings and arrays inside a cluster.

 

The second cluster really is equivalent to a simple boolean passed by reference. Since you do not show the actual type of the boolean it is hard to recommend what datatype to use in LabVIEW. Windows BOOL is a 32 bit integer while C++ bool usually is an 8 bit value which would coincide with the 8 bit boolean LabVIEW is using. You can't configure a boolean parameter directly in the CLN so you could either use an accordingly sized integer or create that cluster with one single LabVIEW boolean anyhow (if your bool is a C++ bool and not something else) and do the same as with the previous cluster/structure parameter.


The type about using Adapt to Type was key.

The original DLL was written in Visual Studio .NET 2003, so the doubles equated to LabVIEW's double, the ints equated to LabVIEW's I32, and the boolean equated to LabVIEW's I16.

 

The next big hurdle will be the complex number arrays that get passed back in a different function. Wish me luck.

 

 

0 Kudos
Message 8 of 14
(4,591 Views)

two more stumbling points:

 

1. function in DLL wants a pointer to an array of doubles

func1(double *freqList).

I tried creating a reference and wiring it to the CLN input, but that didn't work

How do I do this?

 

 

2. function in DLL is

 

func2(parameter1)

 

where parameter is declared as  complex <double> parameter1 [NUM_POINTS]

How do I do this?

 

 

 

 

 

 

0 Kudos
Message 9 of 14
(4,585 Views)

 


@nyc_(is_out_of_here) wrote:

two more stumbling points:

 

1. function in DLL wants a pointer to an array of doubles

func1(double *freqList).

I tried creating a reference and wiring it to the CLN input, but that didn't work

How do I do this?

 

 

2. function in DLL is

 

func2(parameter1)

 

where parameter is declared as  complex <double> parameter1 [NUM_POINTS]

How do I do this?

 


 

For 1) you take a LabVIEW double array when this is an input or using Inilialize Array create one with the correct size and pass it to a CLN paramter configured to be an array of doubles passed as C Array Data Pointer.

 

For 2) I have no idea what the complex syntax item means. This clearly is not standard C but more likely advanced C++ syntax which I haven't bothered to learn everything about.

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