Jump to content
torekp

LV DLL creates mysterious DoubleArray class

Recommended Posts

So I created a DLL from a Labview VI that has a 2D array input (and some scalar inputs) and some 2D array outputs.  Labview creates a .h file with these lines

DoubleArray.PNG

And then it defines the 2D array arguments to my function as being of this type: "void __cdecl Linear_discrim_4dll(DoubleArray *dataObsFeat, int32_t grpAsz," etc etc.  Trouble is, I have no idea how to fill out this structure so that the DLL can use it.  Say for simplicity I had a 2 by 3 input called dataObsFeat with elements {1,2,3; 11,12,13}; how would I create the object with these values in C or C++ and pass it to the function?  I am a total C++ noob, in case it isn't obvious.

Share this post


Link to post
Share on other sites
On ‎11‎/‎04‎/‎2018 at 10:53 PM, torekp said:

So I created a DLL from a Labview VI that has a 2D array input (and some scalar inputs) and some 2D array outputs.  Labview creates a .h file with these lines

DoubleArray.PNG

And then it defines the 2D array arguments to my function as being of this type: "void __cdecl Linear_discrim_4dll(DoubleArray *dataObsFeat, int32_t grpAsz," etc etc.  Trouble is, I have no idea how to fill out this structure so that the DLL can use it.  Say for simplicity I had a 2 by 3 input called dataObsFeat with elements {1,2,3; 11,12,13}; how would I create the object with these values in C or C++ and pass it to the function?  I am a total C++ noob, in case it isn't obvious.

See the memory layout of Arrays at http://zone.ni.com/reference/en-XX/help/371361P-01/lvconcepts/how_labview_stores_data_in_memory/

 

If you create the 2-by-3 array in LabVIEW and pass it to your DLL, you can read it in C/C++like this:

void vi1(DoubleArray *array_fromLv)
{
    double cArray[2][3];
    cArray[0][0] = (*array_fromLv)->element[0];
    cArray[0][1] = (*array_fromLv)->element[1];
    cArray[0][2] = (*array_fromLv)->element[2];
    cArray[1][0] = (*array_fromLv)->element[3];
    cArray[1][1] = (*array_fromLv)->element[4];
    cArray[1][2] = (*array_fromLv)->element[5];

    // Do stuff...
}

 

To pass array data from the DLL to LabVIEW, the idea is to do the opposite:
void vi2(DoubleArray *array_toLv)
{
    double cArray[2][3];

    // Do stuff...

    (*array_toLv)->element)[0] = cArray[0][0];
    (*array_toLv)->element)[1] = cArray[0][1];
    (*array_toLv)->element)[2] = cArray[0][2];
    (*array_toLv)->element)[3] = cArray[1][0];
    (*array_toLv)->element)[4] = cArray[1][1];
    (*array_toLv)->element)[5] = cArray[1][2];
}

 

VERY IMPORTANT: Before your DLL writes any data, you must properly allocate the memory. There are 2 ways to do this:

  • Pre-allocate the array in LabVIEW, pass this array into the DLL, and let the DLL overwrite the array contents, OR
  • Call LabVIEW Manager functions (http://zone.ni.com/reference/en-XX/help/371361P-01/lvexcodeconcepts/labview_manager_routines/ ) to allocate or resize the array before writing the data. These functions are poorly-documented, however.
 

 

Edited by JKSH
Fix code errors

Share this post


Link to post
Share on other sites

Thanks!  Sorry, I wasn't clear.  I'm not trying to use a DLL in Labview.  I'm trying to use a DLL (that Labview created) in C++.  I read the first website on the "C Struct Hack" and tried to apply it to your advice, yielding this:

int i;       
int len = 2, len2 = 3;
int32_t datasz[2]={2,3};
double data1d[6] = { 1,2,3,11,12,13};
double aresult[2][2];
DoubleArray dataouta;
DoubleArray datain;

void viGet(DoubleArrayBase * result)
{
    for (i=0; i<4; i++) aresult[i/2][i%2] = (result->element);
}
void viSet(DoubleArrayBase * myArray)
{
    (myArray->dimSizes)[0] = 2;
    (myArray->dimSizes)[1] = 3;
    for (i=0; i<6; i++) (myArray->element) = data1d;
}

int main(int argc, char *argv[])
{
    viSet(datain);
    Linear_discrim_4dll(&datain,&dataouta,len,len2);
    viGet(dataouta);
)

and some printf statements.  This compiles (yay, a first!) but has a Fatal Runtime Error dereferencing a null pointer to datain, at the call to viSet.

Edited by torekp

Share this post


Link to post
Share on other sites

My apologies, I remembered wrongly and gave you wrong code. I've fixed my previous post now.

The syntax is funny because:

  • DoubleArrayBase is the struct itself.
  • DoubleArray is a pointer to a pointer to a DoubleArray struct (yes, you read that right)
On ‎12‎/‎04‎/‎2018 at 9:46 PM, torekp said:

I'm not trying to use a DLL in Labview.  I'm trying to use a DLL (that Labview created) in C++.

Everything in the first half of my previous post (up to and including the first block of code) still applies to C++ code that reads array data from the DLL.

C++ code that writes array data into LabVIEW is a bit more complex. Look in your LabVIEW-generated header file again: Do you see functions called AllocateDoubleArray() and DeAllocateDoubleArray()?

// In the LabVIEW-generated header, mydll.h
typedef struct {
	int32_t dimSizes[2];
	double element[1];
} DoubleArrayBase;
typedef DoubleArrayBase **DoubleArray;

DoubleArray __cdecl AllocateDoubleArray (int32_t *dimSizeArr);
MgErr __cdecl DeAllocateDoubleArray (DoubleArray *hdlPtr);


// In your code
#include "mydll.h"

int main()
{
	// Allocate and write the input array
	int32_t datasz[2] = {2, 3};
	DoubleArray arrayIn = AllocateDoubleArray(datasz);
	(*arrayIn)->element[0] = 1;
	(*arrayIn)->element[1] = 2;
	(*arrayIn)->element[2] = 3;
	(*arrayIn)->element[3] = 11;
	(*arrayIn)->element[4] = 12;
	(*arrayIn)->element[5] = 13;

	// Call your function
	DoubleArray arrayOut;
	Linear_discrim_4dll(&arrayIn, &arrayOut, 2, 3);

	// Extract data from the output array, ASSUMING the output is 2x2
	double cArray[2][2];
	cArray[0][0] = (*arrayOut)->element[0];
	cArray[0][1] = (*arrayOut)->element[1];
	cArray[1][0] = (*arrayOut)->element[2];
	cArray[1][1] = (*arrayOut)->element[3];

	// Free the input array's memory
	DeAllocateDoubleArray(&arrayIn);

	// ...
}

 

Edited by JKSH
  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.