LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

interface .dll - can I involve some C++ code

Good day,

 

I got some .dll from a supplier and want to use it to calculate some outputs. Cannot upload the .dll for proprietory information.

 

There is some Excel addin that uses the .dll, but nothing for labview. I got some C++ example how to use the .dll

 

pretty much need to create some objett, then a pointer, then some strcopy stuff

 

Steffen01_0-1727343760388.png

 

I tried tools, import shshared library (,dll) but no luck, it only found some functions to return the variables I can get calculated plus their units, such as motor power in kW. So as such it works, but I cannot actually get the .dll to calculate the motor power for me

 

thanks!

 

 

 

0 Kudos
Message 1 of 73
(628 Views)

The little code you show is NOT C++ code. It's pretty much a few calls to copy a string memory buffer to a different string memory buffer and nothing else. It has nothing to do with whatever your DLL may or may not implement nor does it show anything about how that DLL might need to be called.

 

What you showed us so far is similar to showing an image of a bicycle and asking how to get your car started. Not helpful at all!

Rolf Kalbermatter
My Blog
0 Kudos
Message 2 of 73
(600 Views)

Hi,

 

Can you build a simple C++ program to test the function of dll?

To integrate it with LabVIEW you might need to build a wrapper dll.

 

John Medland just did a great presentation and demo on the details of integrating C/C++ code with LabVIEW.

See his repository with instructions and examples here: serenial / GDevCon Integrating C⧸C++ into LabVIEW · GitLab

 

To get the correct data types you can in LabVIEW setup a Call Library function node, where arguments use the "Adapt to Type" type:

JoGra_0-1727418555597.png

 

and then setup your inputs on the block diagram:

JoGra_1-1727418586329.png

 

and then right click the Call Library Function Node and select "Create C file", which creates prototype code for the types that wired into the node. 

Message 3 of 73
(564 Views)

this are the functions that some other software is finding

Steffen01_1-1727423320143.png

this are the wrappers that I can get

Steffen01_2-1727423340770.png

so I can get variable names and units out of the dll. Means I know that it works. This is getunitsforvariable and getvariablename. This as such os pretty useless to me

Steffen01_3-1727423462615.png

 

what I want is at least reatecompressor, but that is not possible to get from the dll

Steffen01_4-1727423616007.png

here it says C++, there is some example for getcompressorefficiency. Which I cannot get a wrapper for

Steffen01_6-1727424367098.png

 

Steffen01_5-1727423669328.png

//---------------------------------------------------------------------------------------------------------------------
// Example 1: Making a TurboCalc Rating using getCompressorEfficiency.
//
// This example details the object initialization process that are the required parameters to rate using the
// getCompressorEfficiency function within TurboCalc.
//---------------------------------------------------------------------------------------------------------------------
void rateWithTurboCalc()
{
std::cout << "Example 1:" << std::endl;

//Create variables to store you input conditions. These will be used to make your compressor rating.
const double evaporatorCapacity = 250;
const double SDT = 27; //Saturated discharge temperature.
const double SST = 5; //Saturated suction temperature.
const double SSH = 3; //Suction superheat.
const double SC = 6; //sub-cooling.

//Create a TurboCalcCompressor object. This object is used in the DLL to specify the compressor, version number,
//and the version number that you wish to use for your rating.
TurboCalcCompressor compressor;
//copy the compressor typecode into the char pointer. This string has SHORT_STRING_LENGTH allocated for its size.
strcpy_s(compressor.typecode, SHORT_STRING_LENGTH, "TTS300-400-ST");
//copy the model data version into the char pointer. This string has SHORT_STRING_LENGTH allocated for its size.
//Using a zero "0" will select the most recent version of the model data for the selected typecode.
strcpy_s(compressor.modelVersion, SHORT_STRING_LENGTH, "0");
//copy the refrigerant type into the char pointer. This string has SHORT_STRING_LENGTH allocated for its size.
strcpy_s(compressor.refrigerant, SHORT_STRING_LENGTH, "R134a");

//Create a TurboCalcParameters object. This object is used in the DLL to specify the the rating parameters used
//to rate your compressor, including the calculation type (from power, capacity, or evaporator mass flow), the
//saturated suction temperature (SST) and saturated discharge temperature (SDT).
TurboCalcParameters parameters;
//Copy the calculation type to use for your rating. This string has SHORT_STRING_LENGTH allocated for its size.
strcpy_s(parameters.calculationType, SHORT_STRING_LENGTH, "FROM_CAPACITY");
//Copy the units to use for your rating. This string has SHORT_STRING_LENGTH allocated for its size.
strcpy_s(parameters.globalUnits, SHORT_STRING_LENGTH, "SI"); //For this example, we are using SI units.
parameters.inputQuantity = evaporatorCapacity; //Set the value based on the calculationType.
parameters.saturatedDischargeTemperature = SDT; //Set the SDT based on the globalUnits selected. C or F.
parameters.saturatedSuctionTemperature = SST; //Set the SST based on the globalUnits selected. C or F.
parameters.suctionSuperheat = SSH; //Set the SSH based on the globalUnits selected. K or R.
parameters.subcoolingTemperature = SC; //Set the SC based on the globalUnits selected. K or R.
parameters.approachTemperature = 0; //Set the economizer approachTemp based on the globalUnits selected. C or F.
parameters.useEcon = false; //Set useEcon True(economizer enabled) or False (economizer disabled).
parameters.ambientTemperature = 0; //Set the ambientTemperature. Only used if using a High Temp (HT) compressor.
parameters.deratedFullLoadAmps = 0; //Set the derated FLA (A). Not used if set to zero.

//Create a TurboCalcUnitOverrides object. This object allows you to use different units than what are default when
//selecting the globalUnits. For example, you can set global units to SI, but specify the temperature to be in
//Fahrenheit using this object. The variables within this object should be an empty string to use the default
//units specified in globalUnits.
TurboCalcUnitOverrides unitOverrides;

//Create a TurboCalcResults object. This object will store the results from the getCompressorEfficiency function
//that define the performance of the rated compressor.
TurboCalcResults outputData;

//Create a TurboCalcError object. This object will store the error message and error code if there is an issue with
//the rating you are attempting to make.
TurboCalcError turboCalcError;

//Pass in the created objects to getCompressorEfficiency to get the compressor's efficiency.
getCompressorEfficiency(compressor, parameters, unitOverrides, outputData, turboCalcError);

//Print the results by accessing the outputData object.
//Results at the specified capacity point:
std::cout << "COP at specified capacity point: " << outputData.coefficientOfPerformance.optimal << std::endl;
std::cout << "Capacity at specified capacity point: " << outputData.capacity.optimal << std::endl;
std::cout << "Power at specified capacity point: " << outputData.electricalInputPower.optimal << std::endl;

//Results at min capacity point:
std::cout << "COP at min capacity point: " << outputData.coefficientOfPerformance.min << std::endl;
std::cout << "Capacity at min capacity point: " << outputData.capacity.min << std::endl;
std::cout << "Power at min capacity point: " << outputData.electricalInputPower.min << std::endl;

//Results at max capacity point:
std::cout << "COP at max capacity point: " << outputData.coefficientOfPerformance.max << std::endl;
std::cout << "Capacity at max capacity point: " << outputData.capacity.max << std::endl;
std::cout << "Power at max capacity point: " << outputData.electricalInputPower.max << std::endl;

//Print the error message associated with rating that just completed:
std::cout << "Error message: " << turboCalcError.errorMessage << std::endl;
}

0 Kudos
Message 4 of 73
(551 Views)

Those TurboCalc* "objects" are treated very much like structs in the example. They could be stack-allocated objects, but I doubt that since I do not see any method to create them from the exported functions. That would be required for any non-C++ code to call the dll.

See if they are structs and defined in TurboCalcLibrary.hpp. You might be able to recreate them in LabVIEW. Depending on how many nested structures they contain that will get complicated fast.

The easier way is to create a wrapper dll by adapting one of the examples. Either way, I encourage you to look at John Medland's repository above, he has a lot of material about the call library node.

0 Kudos
Message 5 of 73
(533 Views)

Well a C class is a structure on stereoids. Rather than only having data elements it also can, but doesn't have to, have methods in a virtual dispatch table. It's mainly this dispatch table that makes classes non-portable between different compilers.

 

Those objects do not really look like normal C++ classes but in fact more like structs. They are also not allocated dynamically (no new operator) but simply instantiated as static elements which makes it even more likely that they are simply structs in reality. The function that gets these "objects" passed to is in fact simply a normal C function, not an object method.

 

Without seeing the actual header file that defines all these things it is however pretty hard to say anything more with any certainty. It looks like it could be called by the Call Library Node. Not by using the Import Library Wizard but by doing the work yourself by hand.

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 73
(518 Views)

 attached the files, there is one called enums, this may be the key to untangle things. The way how they did it before was in SOAP, send 12 different values in (some booleans and some floats), then it returns an array of 30 float numbers. Now it will be something similar, just via some dll

0 Kudos
Message 7 of 73
(481 Views)

ok, drag and drop did not work. Now the files

the library used to be .hpp but the dll import wizzard worked fine when I changed to .h

Download All
0 Kudos
Message 8 of 73
(478 Views)

Steffen01_0-1727490254130.png

 

Steffen01_1-1727490297529.png

ok, so if I manage to figure out what is meant to be in the input, I could get it to work. Is it a string or a bunch of variables. The name does not matter, just in what order? And even boolean does not exist it seems, it will be sent as integer 0 or 1?

0 Kudos
Message 9 of 73
(467 Views)

Forget the Import Library Wizard. This is more than just C declarations put in a hpp file by accident!

 

Yes it is basically a C++ class used as a C struct but!!!

The dtrings in there are dynamically allocated memory buffers and that is going to be painful to do in LabVIEW code and you have to do it all by hand!!

 

How many days do you have to spend on this? Only for 32-bit LabVIEW or also 64-bit? Both need individually different VI code for this to work! And you need to create VIs to allocate, copy into and out of and deallocate these monsters. For each struct (class) containing string members! The ones only containing integers are simply LabVIEW clusters with that many int32 inside.


if you need to support both 32-bit and 64-bit I would write a wrapper DLL in C++ that exports LabVIEW compatible functions. Trying to support those nasty classes containing string pointers natively in LabVIEW isn’t impossible but nasty and quite a lot of work and really almost nobody in the LabVIEW world is going to understand the result and won’t be able to maintain or expand on it themselves. I could do it in maybe one day of work but a wrapper DLL costs about the same effort. The difference is that there are many people who could do that wrapper DLL in a day of work but very few who could do the same in pure LabVIEW in a week and it most likely would still be crashy!

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 10 of 73
(447 Views)