LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Using a labview 2020 dll in another language

Solved!
Go to solution

Hi,

 

My colleague developed a project in labview and I want to use it by calling the compiled DLL. The DLL was compiled on a x64 version.

I first installed the labview 2020 runtime engine. I can then load and use that library in Python.

However when I try to run it in matlab (r2016a) with 

loadlibrary('library.dll', 'library.h')

I get a fatal error:  extcode.h: No such file or directory #include "extcode.h"

 

I then tried to create a Visual C++ project in Visual Studio 2019 and add the generated files *.dll *.h *.ini *.lib but I get the same error with extcode.h not existing and then other errors of uint16_t types not existing, for example.

 

Note that on my machine I do not have labview installed and I only want to use the DLL.

 

Thank you for your help!

Best,

phas

0 Kudos
Message 1 of 7
(242 Views)

The LabVIEW dll is no different than all the other dlls you use.  It needs its runtime to run.  The reason you think you don't need runtimes for the other dlls is because their runtimes have probably been installed by something a long time ago.  Install the appropriate LV runtime.

Bill
CLD
(Mid-Level minion.)
My support system ensures that I don't look totally incompetent.
Proud to say that I've progressed beyond knowing just enough to be dangerous. I now know enough to know that I have no clue about anything at all.
Humble author of the CLAD Nugget.
0 Kudos
Message 2 of 7
(202 Views)

Hi Bill,

 

Thank you for your answer, I do believe that have the appropriate runtime installed as I can run the dll with Python. My issue is about using it in other languages (C++ and Matlab), on the same system as the Python.

 

Best,

phas

0 Kudos
Message 3 of 7
(194 Views)

@phas wrote:

 

loadlibrary('library.dll', 'library.h')

I get a fatal error:  extcode.h: No such file or directory #include "extcode.h"


You tell Matlab to load the DLL and use the according header file for the function definitions that the library exports. However your library.h file that LabVIEW generates depends on the extcode.h file that defines a number of standard types and functions that a DLL could use.

 

The Matlab parser tries to interpret the library.h file and sees that in includes the extcode.h file and that it probably will need that to parse the rest of the header file properly.

 

You can find extcode.h and a number of other header files in your cintools directory inside your LabVIEW installation directory. You do need an installation of the Full Development System of LabVIEW for these header files. Now you need to find a way to tell the Matlab loadlibrary() function to tell the directory where it can find these additional header files.

 

According to the Matlab documentation you need to do something along the lines of:

loadlibrary('library','library.h','includepath','c:\Program Files\National Instruments\LabVIEW 20xx\cintools')
Rolf Kalbermatter
Averna BV
Message 4 of 7
(180 Views)

@rolfk wrote:

You can find extcode.h and a number of other header files in your cintools directory inside your LabVIEW installation directory. You do need an installation of the Full Development System of LabVIEW for these header files. Now you need to find a way to tell the Matlab loadlibrary() function to tell the directory where it can find these additional header files.

 


Hi Rolf,

 

Thank you for your answer, does this mean that while Python did only require the labview runtime, Matlab requires the full software installation?

0 Kudos
Message 5 of 7
(175 Views)

@phas wrote:

Thank you for your answer, does this mean that while Python did only require the labview runtime, Matlab requires the full software installation?


Not really. But the Matlab loadlibrary() function determines the functions you can call from a DLL based on the header file. And in order to be able to parse that header file it needs all the dependencies that are included in the header file.

 

In Python you most likely defined the actual functions you wanted to call by using the ctypes library. This requires more manual work (someone has to define the functions using ctypes) but doesn't require the header file anymore later. In Matlab you can do that too, but it requires you to define the prototypes and datatype mappings yourself. loadlibrary() is a convenience function that TRIES to determine everything from parsing the header file for you. Please not however the word TRIES above. A C header file is in fact notoriously insufficient to describe all aspects of calling function interfaces. It works for simple functions that only take scalar parameters but often goes into the nirvana land of memory corruptions and crashes as soon as the API takes arrays, strings or other complex datatypes as parameters.

Rolf Kalbermatter
Averna BV
Message 6 of 7
(169 Views)
Solution
Accepted by topic author phas

Thank you both for your answers, I finally managed to use the dll and use it in python, C++ and Matlab.

It may be of use for future user so I'll describe here what I did.

 

Since the

#include extcode

 line was a problem as this file only exists if you have the full installation of Labview and I wanted to only use the dll on a computer that didn't have it. While in python I had to redefine every type defined in the *.h file to make it work, I chose the exact same approach in C++ and Matlab (C++ compiled with MEX).

 

For example the header file may contain the following

typedef struct {
    int32_t dimSizes[2];
    uint16_t Numeric[1];
    } Uint16ArrayBase;
typedef Uint16ArrayBase **Uint16Array;
Uint16Array __cdecl AllocateUint16Array (int32 *dimSizeArr);
int32_t __cdecl someFunction(uint16_t var1, char var2[], uint16_t var3[], 
    Uint16Array *var4)

 Which in Python translates as such:

from ctypes import *
class Uint16ArrayBase(Structure):
    _fields_ = [
        ("dimSizes", c_int32 * 2),
        ("Numeric", c_uint16 * 1) 
    ]

Uint16Array = POINTER(POINTER(Uint16ArrayBase))

lib = cdll.LoadLibrary(r'library.dll')
lib.AllocateUint16Array.restype = Uint16Array
lib.AllocateUint16Array.argtypes = [POINTER(c_int32 * 2)]

lib.someFunction.argtypes = [
    c_uint16,
    c_char * ALENGTH,
    c_uint16 * ASIZE,
    POINTER(Uint16Array)
    ]
lib.someFunction.restype = c_int32

Although it is important to note that the Numeric array may not be of length 1 and that you may need to define it differently.

And then I was able to use the function and access the different values using python's ctypes library.

 

While loading the DLL in memory is only one line in Python, in C++ it requires the following:

#include <iostream>
#include <windows.h>
#include <stdio.h>

typedef struct Uint16ArrayBase{
	int32_t dimSizes[A];
	uint16_t Numeric[B]; 
 } Uint16ArrayBase;

typedef Uint16ArrayBase **Uint16Array;
typedef int(__cdecl *MYPROC)(LPWSTR);
typedef int(__stdcall *someFunction)(uint16_t a, char b[], uint16_t x[], Uint16Array *y);

typedef int(__cdecl *MYPROC)(LPWSTR);

HINSTANCE lib = LoadLibrary(TEXT("library.dll"));
someFunction lib_someFunction = (someFunction)GetProcAddress(lib, "someFunction");

To then use my loaded lib_someFunction.

 

For Matlab an added part must be added: 

#include "mex.h"
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){}

The mex.h file comes with the Matlab installation and the mexFunction is the gateway for the MEX functionality to the C++ code more details can be found in the documentations

To then generate a file usable by Matlab the following command must be run:

mex filename.cpp

 where filename.cpp is your source with the mexFunction call, linked to your library. This generates a *.mexw64 (if using windows and a 64-bit Matlab version) that behaves like a *.m function.

 

Hopes that helps someone in the future.

Message 7 of 7
(115 Views)