LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Creating a DLL to work on 2D Arrays

Solved!
Go to solution

I have some LabVIEW code that performs manipulation of 2D arrays. I would like to build it into a DLL that I can give to customers so they do not have to duplicate my work. The arrays represent images, so they can be large (sometimes 20k rows by 2k columns). I currently have them defined as 2D array of U16, but it seems like this will be a real pain for the end user to get this data defined correctly to call the DLL.

 

Are there some better options for passing the image in? 

I was thinking they could send in a filename to a CSV file for example. But then they would have to save the file and LabVIEW would have to load the file which could add a couple of seconds to the process which is not desired.

 

I'd also be ok building an application that runs in the background, but I would like the user to be communicate with it (and not have to click on a GUI).

0 Kudos
Message 1 of 47
(525 Views)
Solution
Accepted by Gregory

What about supporting several so your customers can choose their own balance between execution times and ease/difficulty of formatting?

 

Start with whichever one would run fastest, presumably the a 2D U16 array you mentioned.  Put the meat of it there.

 

Then add wrapper calls to it that allow things like importing as CSV, as greyscale BMP files, or whatever else you come up with.  Then have those unpack the alternate data format, reformat it internally to the 2D U16 array with error checking, then pass it to the code that runs on that data type.  For any customer who requests a different format, add a new type and release an update.

Message 2 of 47
(501 Views)

That's a good idea! It looks like making the DLL with a 1D array input is much more friendly for the user. I'm thinking about asking the user to concatenate all the rows of the image, then input the 1D array, number of rows, and number of columns. Then I can re-shape into a 2D array in LabVIEW.

0 Kudos
Message 3 of 47
(498 Views)

https://pettaa123.github.io/labview-blog/2024/01/02/Read-Array-Using-DLL.html

 

LabVIEW stores a 2d array contiguous anyways. You just have to resize the labview array to fit your image and set the correct dimensions. Done.

0 Kudos
Message 4 of 47
(461 Views)

Hi Quiztus, 

Thank you for the link. I know next to nothing about C++. In the example you shared, it looks like LabVIEW is passing the array into a DLL made with C++, and receiving an array back in LabVIEW, is that correct?

 

If so, I kind of want to do the opposite. I will provide the DLL made with LabVIEW, and the user will call it from C++ (or their language of choice). Does the example still apply in this case?

0 Kudos
Message 5 of 47
(421 Views)

Hi Christy, thank you for the tips. Are memory mapped files like binary files? I've seen binary files load much, much faster than a simple tab or comma delimited file. Since the images may not change too often, I think one compromise could be offering a function that converts a CSV file to a binary file, and then the LabVIEW DLL can load the binary file very quickly. 

 

By the way, how does wrapping the 2D array in a cluster make it easier for the user to pass it to LabVIEW? They would still have to call the functions that rearrange the data before passing it into the DLL, right?

0 Kudos
Message 6 of 47
(412 Views)

Christi is most likely a bot. The answer was 100% AI.

 

Please share a simplified dll and header of your use case. 

In the best case scenario you just have to pass the c++ managed pointer and dimensions to your labview created dll.

If you don't fork the wire in your labview code, this could result in zero copy and ultimately best performance. Worst case you have to create a full copy into a LabVIEW managed array init'd via DSNewPtr from extcode.h

0 Kudos
Message 7 of 47
(394 Views)

Hi Quiztus, attached is a LabVIEW project with the DLL in the "build" folder.

 

I was thinking about having my standard function "CalcImage". And then, thanks to Kyle's suggestion, I would have a wrapper called "CalcImage1D" where the 2D arrays are represented as clusters of: 1D Array, Num Rows, Num Cols.

0 Kudos
Message 8 of 47
(389 Views)

I did a  vi dll, which simply increments the 2D u16 array. Using the LabVIEW memory manager works, even deallocation throws error 108, dunno. Maybe someone else can put light onto this.


Allocating the 2d array in C using malloc doesn't work. Since I am on 64 bit LV, it can't be a padding issue. Again, maybe someone else can enlighten us.

the zip contains the c code and my project saved in 2019.




0 Kudos
Message 9 of 47
(363 Views)

I can't test it at the moment but maybe try something like this:

 

int32 dimSizeArr[2] = { 5, 10 };
Uint16Array in, out = NULL;
MgErr err;

in = AllocateUint16Array(dimSizeArr);
if (in == NULL) {
	std::cerr << "Failed to allocate memory for in" << std::endl;
	return 1;
}
(*in)->dimSizes[0] = 5;
(*in)->dimSizes[1] = 10;

for (int i = 0; i < 50; i++) {
	std::cout << static_cast<int>((*in)->elt[i]);
}
std::cout << std::endl;

//inc in labview dll
CalcImage(&in, &out);

if (out)
{
    std::cout << static_cast<int>((*out)->dimSizes[0]);
    for (int i = 0; i < 50; i++) {
	std::cout << static_cast<int>((*out)->elt[i]);
    }
    err = DeAllocateUint16Array(&out);
}
err = DeAllocateUint16Array(&in);

std::cout << std::endl;
Rolf Kalbermatter
My Blog
Message 10 of 47
(401 Views)