LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Making a LVDLL and call it from C, containing clusters and Arrays of Clusters

Solved!
Go to solution

Hello!

 

I've tried a few ideas on how to make a LV DLL that others can call in C. This works just fine as long as I don't use clusters. It's just a matter of settings I'm sure. However I find lots of information on how to call a C-DLL from LabVIEW and pass a cluster to a struct input. But not much at all on how to create a LV function->convert to dll->call it in other software or LV.

 

I've made a very small example program attached, where I've both the VI that is built to DLL and a tester VI to test the built DLL. LV just throws me exceptions...

 

Anyone has some ideas on how to setup either the build, convert the cluster or configure the call library function node properly to read and write my data as I want?

Best Regards
Jonas Mäki
Systems Developer
Novator Solutions
0 Kudos
Message 1 of 13
(3,376 Views)
Solution
Accepted by topic author JonasM

It would help if you did a save for previous and save it to LabVIEW 2015 or some earlier version, to allow more people to look at it.

 

One of the basic trouble you have in the way you defined your C interface is that you pass absolutely no information to the DLL about how large your arrays are. In C, buffers have to be provided by the caller both for input and output parameters and the function needs to actually know how many elements are in the array to process. Of course you could assume a fixed number, but you know what they say about assumptions. They are always wrong!

Rolf Kalbermatter
My Blog
Message 2 of 13
(3,354 Views)

I managed to get it working by defining length as suggested by Rolfk and also set the param type as input/output.

 

Now saved in 2013 attached.

 

I will continue to make it more complex, as I will need an array of clusters containing arrays and even clusters of fxp data. Not sure how that will be handled.

Best Regards
Jonas Mäki
Systems Developer
Novator Solutions
0 Kudos
Message 3 of 13
(3,341 Views)

Do you mean fixed precision numbers or extended precision floating point with "fxp"? Both are likely bad ideas as fixed point arithmetic is in fact a custom data format and needs extra information, that is not part of the data itself, about the actual precision of the number, while extended precision floating support is not present in Visual C for instance (NI implemented that all themselves with direct assembly programming of the FPU), and there are different ways of implementing it in the C level for C compilers who support it. The NI extended float format is the x87 FPU 80 bit format, while most conforming compilers that actually support extended, like recent gcc compilers implement the standard IEEE "long double" format which is a 128 bit number that gets then packed into the 80 bit format for x86/87 CPUs for the actual operation or optionally use a software 128 bit arithmetic runtime library.

Moreover the 80 bit x87 FPU format has been deprecated by both AMD and Intel for a long time in favor of faster (but less precise, with the exception of some anamolies in the x87 FPU implementation for for instance the sin() function) MMX operation and Microsoft initially even disabled it on Windows 64 bit, but then added support for it back in, but highly discourages its use on 64 bit Windows.

 

And arrays of clusters containing arrays is another VERY bad idea for providing a C interface to LabVIEW functions. Those arrays embedded inside the clusters will all be LabVIEW array handles, something that can only be allocated, resized and deallocated by the LabVIEW memory manager functions. No real problem to do that when everything runs inside LabVIEW but if your external application is something else (and why would you otherwise want to provide a DLL if it wasn't something else than LabVIEW) then you will be in real trouble to get at the right memory manager functions that the LabVIEW DLL uses to operate on those arrays. And I doubt you want to write a 100 page chapter in your library documentation about how a programmer using your DLL needs to get at those functions and use them to provide the necessary array handles inside those complex datatypes!

Rolf Kalbermatter
My Blog
Message 4 of 13
(3,338 Views)

We have decided not to use arrays within the clusters contained in the arrays. As we want a lib that is not too hard to understand and use.

 

However we are still in need of fxp and by that I mean fixed point numeric. I've attached a small example. The one named clusterincluster. This doesn't work as expected and your previous post says why. We will have to think about how we can convert those.. Any suggestions?

Best Regards
Jonas Mäki
Systems Developer
Novator Solutions
0 Kudos
Message 5 of 13
(3,326 Views)

It should sort of work but not likely as you expect it to work! Basically assume you define a FXP of word size = 50 and integer word length = 32. 

 

This means the entire length of the fixed precision number should be 50 bits but since there is no integral C datatype that provides 50 bits exactly LabVIEW uses the next bigger integral datatype which happens to be an int64.

 

So of those 64 bits, 50 are used and the rest is garbage. Now the interesting part is how these 50 bits are placed in the bigger 64 bits! Basically the first 50 - 32 bits are the fractional part while 32 bits are the integer part and the most significant 14 bits are unused. But those most significant bits are sign extended for negative numbers!!

 

Basically you will have to specify for each function what is the actual fixed point format it uses (and the user can't change it at all as it is compiled into the DLL), and also add a chapter about how the user will need to interpret the bits in order to do anything with those fixed point values.

 

The real question here is, why do you want to make your and the users of your library lifes so miserable? Smiley Very Happy

 

The advantage of fixed point arithmetic is mostly on hardware targets like FPGA where implementing arithmetic on numbers is pretty trivial for fixed point but immensely costly for floating point numbers. In a software library fixed point numbers provide little advantages but pose a huge liability because they are not standard.

Rolf Kalbermatter
My Blog
0 Kudos
Message 6 of 13
(3,323 Views)

In the LV function we are in the end sending this data to an FPGA. This is why we have FXP. But we will look at converting double numbers to FXP in the wrapper and the C function will then just use struct with doubles.

Best Regards
Jonas Mäki
Systems Developer
Novator Solutions
0 Kudos
Message 7 of 13
(3,313 Views)
Solution
Accepted by topic author JonasM

@JonasM wrote:

In the LV function we are in the end sending this data to an FPGA. This is why we have FXP. But we will look at converting double numbers to FXP in the wrapper and the C function will then just use struct with doubles.


That's the approach I would recommend. No need to burden the user of your library with the details of your FPGA implementation.

Rolf Kalbermatter
My Blog
Message 8 of 13
(3,307 Views)

Our API is built around classes and therefore having object ref in and out. This we have wrapped into other VI's and send out the DVR ref num to the caller to keep and use between calls. With the create functionality adding the ref to an FGV that will be accessed in Get mode every time a method is called.

 

I can share my project but it's in 2016 and using GOOP so it will need lots of dependencies. For now I just share a few images of interesting calls. As well as an example that I get working in C.

 

My question now is if this is unsafe in some way, mostly thinking about the reference being alive.

Will the program calling this DLL in C or whatever ADE hold the DLL in memory and will the reference in the FGV stay alive?

The tests I've done suggest so, but I'm not 100% sure.

Best Regards
Jonas Mäki
Systems Developer
Novator Solutions
0 Kudos
Message 9 of 13
(3,290 Views)

I've taken out all stuff around, now it only contains the class and the two test VI's to test the wrapped functions both with DLL and with direct wrappers. To get a better understanding of what I mean "keep alive" the reference.

 

The previous post still has the valid C example written in CVI and have shown to work well. But as I said in previous post, some colleagues here thought it was a bit unsafe to just assume that the DLL would hold that FGV in memory and the calling program to hold the DLL in memory until destroy function.

Best Regards
Jonas Mäki
Systems Developer
Novator Solutions
0 Kudos
Message 10 of 13
(3,283 Views)