05-10-2020 04:05 AM
I have a cluster in Labview, which consists of three different clusters. This cluster is passed to a C++ DLL function using the "Call Library Function Node", and by setting the parameter there "Adapt to Type" (Type) and "Handles by Value" (Data format).
Lets assume for the purpose of illustration, and not to overwhelm you guys with the huge set of parameters, and names, that my clusters are of the following form:
C1:
{
int i_1;
double d_1;
};
C2:
{
int i_2_1;
int i_2_2;
int i_2_3;
};
C3:
{
int i_3_1;
int i_3_2;
};
So the Cluster C = {C1,C2,C3} is the cluster I am passing to the DLL function.
The corresponding Structures at the C++ side are:
struct S1
{
int i_1;
double d_1;
S1 (): i_1(0), d_1(1.0) {};
};
struct S2:
{
int i_2_1;
int i_2_2;
int i_2_3;
S2 (): i_2_1(0), i_2_2(0), i_2_3(0) {};
};
struct S3:
{
int i_3_1;
int i_3_2;
S3 (): i_3_1(0), i_3_2(0) {};
};
S = {S1;S2;S3;};
The DLL function is of the form: extern "C" _declspec(dllexport) void foo(S* params);
This all runs smoothly and nice.
The problem occurs, when I try to add a new parameter to one of the above clusters/structs.
For example, if I attempt to add to C1 a third parameter - int i_1_new; and accordingly adding int i_1_new; to S1, where now
C1:
{
int i_1;
double d_1;
int i_1_new;
}
and
struct S1
{
int i_1;
double d_1;
int i_1_new;
S1 (): i_1(0), d_1(1.0),i_1_new(140) {};
};
ALL the parameter values in the C cluster look in tact and are correct upon calling the DLL function. When debugging the "foo" function at the first line - I get the following: S1 struct is in tact - all values are correct and in place, but S2 gets corrupted such that if the data should be:
S2 = {123,456,789}, it is now {0,123,456}, and the third parameter of S2 is shifted to S3's first parameter (i.e i_3_1 = 789 now).
I'm using a 64 bit LabVIEW 2018, and Visual Studio 2010.
Any suggestions as for how to solve this problem, and why it occurs?
Thank you!
05-10-2020 08:58 AM - edited 05-10-2020 09:01 AM
Instead of doing this elaborate pseudo code to describe LabVIEW clusters you are trying to match to C structs, please add a real example of a sample C code and a LabVIEW VI that exhibit this problem. I tried to follow your pseudo code description and lost somewhere along the wire (sic!) of what you are trying to describe.
It seems to have to do with alignment rules. And there might be even a difference if you actually use C++ or C to compile the actual code. As it seems now you definitely use C++ to compile the struct definitions, otherwise the initialization statements in there would create compiler errors.
LabVIEW does specifically only try to follow standard C conventions. The C++ ABI is notorously compiler and even version specific, so trying to follow that is for an application like LabVIEW, which is multiplatform, simply not an option.
05-11-2020 12:21 AM - edited 05-11-2020 12:39 AM
Thank you for your reply, rolfk.
I understand that the pseudo code of my example is less fun to look at than "real" LabVIEW clusters and C++ structs, but I tried to make it easier on you guys, since my original clusters and structs, are way too overwhelming. I will try to create a small example, hoping this behavior also happens on a smaller scaled objects.
When you say that "LabVIEW does specifically only try to follow standard C conventions", how does it apply on data structures, and other conventions, such as std::string vs char arrays, the dll setup, etc?
I came upon this when reading about setting exporting/importing visual c++ DLL functions:
"If you want plain C exports, use a C project not C++. C++ DLLs rely on name-mangling for all the C++isms (namespaces etc...). You can compile your code as C by going into your project settings under C/C++->Advanced, there is an option "Compile As" which cooresponds to the compiler switches /TP and /TC." -- Is this what I need to do with each dll I want to use with LabVIEW? Does it come instead or in addition to making sure all my exported functions and data structures are "C aligned"?
Thank you,
Benji
05-11-2020 05:03 AM - edited 05-11-2020 05:08 AM
Well if you choose to compile with C instead of C++ your project can not contain any cpp files nor any C++ syntax elements anywhere including the headers.
Similarly you show C++ style initializers in the struct declarations and that shouldn't compile in a C++ compiler if you surround those declarations with extern "C". It might but that would mean they made some strange modifications to recent Visual C compiler versions that I would consider buggy.
Assuming that the example you gave is sympomatic for the problem you see, it should be very easy for you to create an example by just using that code translated into a real example. If that specific example does not cause the error, then there is anyhow nothing we could tell you about what might cause your issue.