07-26-2010 02:59 PM
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?
Solved! Go to Solution.
07-26-2010 05:37 PM
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.
07-26-2010 05:40 PM
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.
07-27-2010 01:22 AM - edited 07-27-2010 01:24 AM
@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.
07-27-2010 01:30 AM
@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.
07-27-2010 04:54 AM
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.
07-27-2010 09:15 AM
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.
07-27-2010 01:52 PM
@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.
07-27-2010 03:04 PM
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?
07-27-2010 03:12 PM
@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.