LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

DLL custom data type

Solved!
Go to solution

Unfortunately I cannot test your code to try some possible solutions. Your DLL appears to be compiled as a Debug (not Release) version, linked against MSVCR100D.dll, which I do not have available because I don't have Visual Studio at home. I might be able to try it at the office next week if I have time, but if you can recompile as a release that would help. Also, please clean up your LabVIEW code. There is no need for the stacked sequence structure nor so many local variables. Can you provide a very simplified VI that does nothing other than call the DLL, with no loops, event structure etc?

 

In order to provide a solution, I need to know how the global_locs parameter should be configured. Most likely you either need to pass a fully-allocated array of some size, or you need to pass an empty structure with no data allocated and allow the function to do the allocation, but I don't see any way to determine if either of these is correct from the information you've provided.

0 Kudos
Message 21 of 26
(1,379 Views)

I just tried your code at the office, where I do have Visual Studio. The test "Hello World" function runs fine, so I can load the DLL. The calculateRowingPattern function generates an error and I cannot do anything further without more information from you as described in my previous posts. This isn't a LabVIEW-specific problem; there isn't enough information to be able to call this function from C, either. I also note that the helper functions for allocating arrays described in the Matlab link are not available in your DLL.

0 Kudos
Message 22 of 26
(1,353 Views)

Hi nathand,

 

Thanks for looking into this.

It "sort" of works with a C++ wrapper I've been trying to code. This wrapper uses the API functions described in the documentation from Matlab to allocate memory dynamically safely. Basic examples work:

1) get some Matlab code,

2) generate C++ code for it, (inside Matlab)

3) use a wrapper to export arguments with primitive data types (not the emxArray_RealT) and

4) finally using a constructor and invoke nodes inside LV to get the right output

 

However in the example I've posted, LV just crashes. Will send you a VS project with that wrapper later on.

Cheers,

E

 

0 Kudos
Message 23 of 26
(1,344 Views)

I know this thread has run cold, but as I recently got over a similar issue I am posting what I did to interface LabVIEW to a DLL function generated with Matlab Coder with input arrays with variable sizes. 

 

If predefined fixed sizes are used it is trivial so I'm not covering that here.

 

As mentioned earlier, for variable size input and output arrays, Matlab uses type emxArray_<basetype> .  This basically includes a pointer to your LabVIEW array, the number of dimensions (say 2), the sizes of those dimensions (say 480 and 640 e.g. numRows and numColumns for an image), and a flag indicating whether Matlab can wipe your array when it is done (no!).  

So you want to create a wrapper function that is called by LabVIEW instead of the one provided by Matlab Coder.  You don't want to call this:

__declspec(dllexport) double testVariableSizeArray(const emxArray_real_T *inArr);

you prefer to call this:

__declspec(dllexport) double Wrapper_testVariableSizeArray(double* data, int numRows, int numCols);

Thus create an additional wrapper function like so:

double Wrapper_testVariableSizeArray(double* data, int numRows, int numCols)
{
	emxArray_real_T y;
	int sizes[2] = {numRows, numCols};

	y.data = data;
	y.size = sizes;
	y.allocatedSize = numRows*numCols;
	y.canFreeData = 0;
	y.numDimensions = 2;

	return testVariableSizeArray( &y );
}

Compile this function to a DLL using your tool of choice.  I used Visual Studio 2010, compiling to a Win32 Release DLL (I use 32bit LabVIEW 2017).

Then call it in LabVIEW:

CallDLL.png

 

 

 

 

 

 

 

 

This function was simply summing the input array, but note that LabVIEW arranges its data row-wise while Matlab defaults to column-wise.  This can lead to unexpected results so make sure to select 'row-wise' when using Matlab Coder.  

Disclaimer: I am not an expert.

Message 24 of 26
(1,218 Views)

Hi Anthon,

 

Thank you for posting this a few years back. This has been the only reference I can find to implement DLLs with a variable size array input. Could you speak more to the process of writing the wrapper function in Visual Studios?

 

I am a beginner programmer when it comes to C++ and shared libraries. Is the wrapper function a .cpp file or .h file? Is the .dll file produced by Matlab coder referenced by LabVIEW, or does Visual Studios produce a new .dll file to be referenced.

 

Thank you for your insight!

0 Kudos
Message 25 of 26
(821 Views)

Just to throw in another option, and yes this is actually documented in several places. It just is not so easy to find the needle in the haystack!

 

#include "extcode.h"
/* Make sure to use the right alignment */
#include "lv_prolog.h"
typedef struct
{
    int32_t dims[2];
    double elms[1];
} Double2DArrRec, *Double2DArrPtr, **Double2DArrHdl;
/* Reset the alignment to what it was before */
#include "lv_epilog.h"

EXTERNC __declspec(dllexport) double Wrapper_testVariableSizeArray(Double2DArrHdl array)
{
	emxArray_real_T y;

	y.data = (*array)->elms;
	y.size = (*array)->dims;
	y.allocatedSize = (*array)->dims[0] * (*array)->dims[1];
	y.canFreeData = 0;
	y.numDimensions = 2;

	return testVariableSizeArray(&y);
}

 

Yes this needs to be put in a .c file (or .cpp if you absolutely insist).

 

Change the Call Library Node to have only one parameter, change it to:

Type: Array, Data Type: 8-byte Double, Dimensions: 2, Array format: Array Handle

rolfk_0-1732542254847.png

 

Rolf Kalbermatter
My Blog
Message 26 of 26
(183 Views)