LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

dll import gets 1097 Error or crash

Hi,
I'm looking for help on integrating in Labview 2022 Q3 64-bit a dll generated in C from Matlab Coder to elaborate a 2D_in array (image) and generate a 2D_out array.
The arr_in is an image of n x n points, where n is not predefined and can vary (typically between 200 and 1000).
 
I tried  importing the dll both using the import wizard or doing it manually in a Call Library Function node.
 
I could find no way to set 2D arrays as  for arr_in and arr_out parameters
 
The only possibility I could find is to set the arr_in and arr_out parameters in the Call Library Function node as numeric, pass by array, and fix a specific length (in my case I guess it should be the maximum expected length, i-.e 1E6 for a n=1000). In this case I have to pass 1D arrays, but I always get this 1097 error code or, worse, a crash(see below).

FabioR_0-1734001895704.png

 

As an example, I compiled a testfunc_arr.dll (attached below) from the following matlab code 


 FabioR_0-1733999390042.png

 

In Matlab this code generates arr_out adding +1 to all the elements of arr_in. It works whatever the dimensions or size of arr_in.

 
I attach here both the dll and the vi resulting from the import wizard procedure.
 
Can somebody help?
 
Thank you
 

Fabio
 

 
Download All
0 Kudos
Message 1 of 12
(565 Views)

The LabVIEW Call Library Node is strictly standard C compatible. What you show is however Matlab code. The Matlab compiler does a rather elaborate translation from its trivial looking syntax to something which is compatible with C programming.

 

Basically the Matlab code you show is absolutely useless in determining how the whole thing will need to be interfaced when Matlab has compiled it to a C DLL. Instead you will need the actually generated C header file and painstakingly make the Call Library Node follow that. And yes that may not be always possible. LabVIEW doesn't (easily) deal with C pointers, even less easily with C structures containing such pointers.

 

Typically your arr_in and arr_out will be a double pointer to an mxArray datatype in C, which is a fairly involved C data structure that is NOT just a pointer. It's pretty much not possible to interface that directly with the LabVIEW Call Library Node, unless you feel very adventurous about playing low level C compiler yourself.

 

Instead you should work through this tutorial very painstakingly and understand all the specialties of this, including the creation of the intermediate DLL to translate between the Matlab mxArray and normal LabVIEW datatypes. And yes it involves C programming, but trying to avoid the intermediate DLL would only mean that you need to know even more about how a C compiler aligns data in the memory and how to do involved pointer arithmetic.

 

 

Rolf Kalbermatter
My Blog
0 Kudos
Message 2 of 12
(543 Views)

Probably the update. I'm having the exact same issue right now. Can't open anything. Ctrl alt del goes to a black screen. Already booted and rebooted so many times

 
0 Kudos
Message 3 of 12
(522 Views)

@pokelto3 wrote:

Probably the update. I'm having the exact same issue right now. Can't open anything. Ctrl alt del goes to a black screen. Already booted and rebooted so many times

 

Well, this is expected result (but such "freezing" is unusual, the Windows is more or less resistant for the exceptions).

 

Anyway, it is slightly a little bit more complicated than you expect.  

Because of this — MATLAB: Use C Arrays in the Generated Function Interfaces.

Probably you noticed, that in the exported DLL is not only one single function, but a little bit more payload.

Something like that should work (created quick and dirty, I haven't checked thoroughly for memory leaks, etc):

snippet.pngMay be some simplifications are possible, but hopefully overall idea is clear more or less.

In general you don't need arr_out as input, but I will leave it "as is" in your original VI.

Attached VI in LV2018.

0 Kudos
Message 4 of 12
(508 Views)

Dear Rolf and Andrey,

thank you for your very appreciated help.

Obviously my dll will do more than add 1 to the array elements. 

My actual dll will have a 2D array in and a 2D array out (but I can make them 1D arrays in labview before sending them to the dll) and some double parameters as input.  Would the vi you sent work regardless of the dll I'll use?

 

Let me explain the issue:

 

I'm not an expert programmer: I'm a scientist working in a research institute and I want to produce a free-to-use executable to be published in a scientific paper and make it available for free to the scientific community worldwide.

Basically, the program generates two images (two lattices made of round 2D-gaussian objects simulating atoms) and add them to get a third image as output (Moiré image). By rotating the 2nd image of an angle between 0 and 360°, step 1°, you get 360 images as output that must become frames of a movie file. 

I used labview+vision development module (VDM) and produced my working software, but then I realized that VDM runtime needs licencing for users to run it.

I tried using matlab script, but it's the same with matlab: the user needs a licence.

In this forum I read that the only way to make the software freely distributable is to make dlls with matlab and integrate them in labview, and here I am...

 

What I need that is not in labview (or it's extremely slow) is:

1) a dll to rotate an image of a given angle (possible in labview, but too slow)

2) a dll that saves the so obtaind images in a movie file, eg. avi, mpg or whatever... (possible only using VMD or labview)

 

Doing it using VDM was quite straightforward.

With matlab I have more difficulties, but I think I can manage doing it.

 

The main problem now is to integrate the dlls in labview without errors.  

 

Obviously, if you have other suggestions to obtain a freely distributable executable (needing only the labview runtime engine that is usable for free) it would be very appreciated.

 

in the meanwihile I'll try to study Rolf's link and implement Andrey's vi with my dlls

 

Thank you!

0 Kudos
Message 5 of 12
(457 Views)

You can do it for 2D as well (and your DLL from MATLAB is already "prepared" for that). Just modify it something like that:

Snippet2D.png

If you will accurately strip down into SubVIs, then it will looks more accurately.

And it works:

Screenshot 2024-12-13 13.08.15.png

On the other hand, if you need to rotate image by one degree and save it to video ("for free"), then I would like to recommend to take a look into OpenCV, it is really much easier than in MATLAB.

0 Kudos
Message 6 of 12
(445 Views)

@FabioR wrote:By rotating the 2nd image of an angle between 0 and 360°, step 1°, you get 360 images as output that must become frames of a movie file. 

If I'll do it with OpenCV, then it will be like this:

 

This is the code for rotation:

 

IMAGEROTATOR_API void fnImageRotator(ImageArrHdl src, ImageArrHdl dst, double angle, LVError* Error)
{
    Mat  M, Dst;
    int width = (*(src))->dimSizes[0];
    int height = (*(src))->dimSizes[1];
    Size size(height, width); //rows, cols
    if (!((*(src))->pixel)) { SetError(Error, true, OCV_NULL_POINTER, "Null pointer"); return; };
    Mat Src(size, CV_8U, (*(src))->pixel, width);

    //https://docs.opencv.org/4.x/da/d6e/tutorial_py_geometric_transformations.html
    M = getRotationMatrix2D(Point((width - 1) / 2, (height - 1) / 2), angle, 1.0);
    warpAffine(Src, Dst, M, Size(width, height));

    MgErr err = NumericArrayResize(uL, 2, (UHandle*)&(dst), width * height);
    (*(dst))->dimSizes[0] = width;
    (*(dst))->dimSizes[1] = height;

    uint8_t* pixel_out = (*(dst))->pixel;
    uint8_t* pixel_in = Dst.data;

    if (!pixel_in || !pixel_out) { SetError(Error, true, OCV_NULL_POINTER, "Null pointer"); return; };
    // Copy,line by line, the image into the LabVIEW Arrray
    for (int y = 0; y < height; ++y) {
        memcpy_s(pixel_out, width, pixel_in, width);
        pixel_out += width; pixel_in += width;
    }
}

 

And this is how to write frames to the Video:

IMAGEROTATOR_API void CreateVideo(char* file, ImageArrHdl src, LVError* Error)
{
    Size size = Size((*(src))->dimSizes[1], (*(src))->dimSizes[0]);
    vid = new VideoWriter(file, VideoWriter::fourcc('m', 'p', '4', 'v'), 25, size, false); //False - Grays
    if (!vid) SetError(Error, true, 5000, "Unable to open Video File");
}

IMAGEROTATOR_API void AddFrame(ImageArrHdl src, LVError* Error)
{
    Size size((*(src))->dimSizes[1], (*(src))->dimSizes[0]); //rows, cols
    Mat frame(size, CV_8U, (*(src))->pixel, (*(src))->dimSizes[0]);
	vid->write(frame);
}

IMAGEROTATOR_API void VideoClose(LVError* Error)
{
    vid->release();
}

 

And LabVIEW code:

 

Snippet.png

I will leave code on GitHub, may be will be useful someday for someone.

Errors handling is minimal and I'm too lazy to pass vidfeowriter as parameter, therefore global var, but it is just an example.

0 Kudos
Message 7 of 12
(425 Views)

Wow, Andrey! Thanks a lot.

I'll spend my Xmas holidays studying your suggestions.

If I manage making the exe and publishing it, I'll acknowledge your help in the paper

 

Thank you

 

Fabio 

Message 8 of 12
(421 Views)

Dear Andrey,

I see that here you don't use memory management like MoveBlock, but just send the 2D arry as an "Adapt to type" parameter . Is this due to the fact that you are not using matlab to build the dll? I'm no programmer, so please excuse silly questions.

Concerning your code on Github, it's not running because the dll is seemingly missing:

FabioR_0-1734250991261.png

Finally, you suggested to use OpenCV. As far as I understood, one can use it in Python or in C/C++. Would it be the same if I want to build a dll to be imported in Labview? I'd prefer Python since it is seemingly simpler to learn than C/C++

 

Thank you

 

Fabio

0 Kudos
Message 9 of 12
(365 Views)

@FabioR wrote:

Dear Andrey,

I see that here you don't use memory management like MoveBlock, but just send the 2D arry as an "Adapt to type" parameter . Is this due to the fact that you are not using matlab to build the dll? I'm no programmer, so please excuse silly questions.

Concerning your code on Github, it's not running because the dll is seemingly missing:


Oh, sorry, it was removed by the default .gitignore. The missing files have been added now. The DLL was compiled using Visual Studio 2022. I assume you should be able to rebuild it, as generally you shouldn't run third-party binary code on your PC (but in this particular case, you can trust me). You may need the latest Microsoft Visual C++ Redistributable if it's not already installed on your PC.

 

You can use OpenCV in Python, but this will give you an additional dependency on Python and a performance penalty when transferring images to and from the Python script. In general, Python isn't necessary here at all; it's just an illusion that it will 'simplify' development. I still recommend using C++. If you don't have Visual Studio, I can show you how to do it using gcc (which is free).

 

Passing a 2D array as Adapt to Type will give me the array's dimensions inside the DLL and, additionally, the ability to resize (reallocate) memory for the destination also inside the DLL. Otherwise, you have more wiring work outside the DLL. Passing an Error Cluster as a parameter is also convenient in some cases.

 

0 Kudos
Message 10 of 12
(356 Views)