LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Help configuring the call library function to initialize a 2D array

Solved!
Go to solution

Hello everyone,

 

I would like to create a simple DLL using LabVIEW (initialized a 2D array and return the square values in a 2D array). Then, I would like to call the DLL from the Call library function of Labview.

I can create a DLL. However, I have some troubles when I am trying to configure the inputs of the call library function.

Indeed, I do not find how to correctly set the inputs in order to allocate memory for the 2D array. As a consequence I can not test the library function because LabVIEW crash. 

 

I check the examples showing the data passing between the DLL and library functions, if I am not mistaken the examples working on the 2D array already built. Unfortunatelly, I do not find the VI which have been used to create the DLL.

 

My question is: how to set the inputs parameters to correctly allocate memory (2D array). Especially, when you want to create a new 2D array from 0 in the VI?

 

Thank you in advance for your help, 

Best regards 

 

problem allocate memory.jpg

 

 

     

0 Kudos
Message 1 of 3
(1,023 Views)

Does your function signature really match what you configured in the dll build spec?

0 Kudos
Message 2 of 3
(964 Views)
Solution
Accepted by topic author Mathias33

Several problems with this:

 

1) You do not show the build specifications for the DLL that define how the Untitled3.vi controls are mapped to the C function prototype.

 

2) Memory management isn't as easy as you imagine. While you can easily pass around arrays in LabVIEW since LabVIEW's managed environment does all the necessary care for you, this does not work automatically when calling DLL functions, since the DLL interface was designed to work with C semantics and they do not provide any way of managed contract. It is all up to the programmer of a function to define how the memory needs to be managed and any caller better has to adhere to that or otherwise crash. But there are also no methods to specify how the interface expects to work, so it is all in the library documentation as prosa text and the caller has to understand that and apply it.

 

When you create a DLL from a LabVIEW VI you have a few configuration choices, but it doesn't allow you to use every possible choice that a C programmer could use. Consequently your caller has to be aware of how the DLL function was created.

 

The most important conclusion here is, it is totally and utterly useless to try to create a LabVIEW function to allocate an array and export it with C syntax. There is no way to return an array pointer back to the caller in this way since the memory the LabVIEW function generates is not accessible from the caller in this way.

 

You could choose in the Build Specification to pass native LabVIEW data out of the DLL, then it will work. But that is likely not useful at all, since when you do that you only can call such a DLL from LabVIEW and then why would you even want to do that? It's easier to call the VI directly from LabVIEW.

 

Now there is another options actually. You can simply export the main function in the DLL to use LabVIEW native datatypes. If you do that the LabVIEW DLL builder will add extra exported functions to the DLL that allow a caller to allocate, resize and deallocate the memory buffers. Any caller of your LabVIEW DLL will however need to be aware of to use these functions whenevr he intends to modify the array. Call of standard C functions like malloc() and free() will fully predictably crash.

 

Included is a project example that shows you how it could be done, and also how this function would need to be called from a C program:

 

// In addition to the actual Square() function the DLL also exports
// memory manager functions which need to be called whenever
// the caller wants to allocate, resize or dealloate the array
#include "testFunction.h"

MgErr err;
int32 dimSizes[] = {3, 4}; 
Int32Array arrHdl = AllocateInt32Array(&dimSizes);
if (arr)
{
    int32 cols = (*arr)->dimSizes[0];
    int32 rows = (*arr)->dimSizes[1]

    for (int32 col = 0; col < cols; col++)
    {
        for (int32 row = 0; row < rows; row++)
        {
             (*arr)->elt[row * cols + col] = row + col;
        }
    }
    err = Square(&arrHdl);
    if (!err)
    {
         // Do something with the data in the array
    }
    err = DeAllocateInt32Array(&arrHdl);
}
else
{
    // out of memory error
    err = mFullErr;
}

 

 

Rolf Kalbermatter
My Blog
Message 3 of 3
(960 Views)