04-06-2024 02:56 AM
I built a labview VI that takes two controls and adds then and puts the result in a indicator..the dll works fine....when I try to build a dll with an array as the output I cant seem to get it to function.....
Maybe I'm missing some steps for the array case.....
04-06-2024 04:25 AM - edited 04-06-2024 04:27 AM
The problem is usually not to create a DLL in LabVIEW that creates an array but the caller needs to be correctly setup. Standard C memory handling rules apply!
Much easier is to allocate the buffer for the array in the caller and let the DLL function write the array elements in there.
From the very helpful code you forget to attach, that’s as much as we can basically tell you.
04-06-2024 02:54 PM
VERY SORRY ! Here is the process I went through but when I try and read the array in a C/Python environment I can't read the array so my set up must be wrong as you have indicated.....
OK...I have attached the VI I then put it into a project folder I then proceeded with the building of the DLL and this is where I get lost....
The tool generates len and len 2 which I suspect is related to the array lengths ? However in the return value option it shows no output...aka void in the H file which I have also attached...what am I missing.....
04-06-2024 02:56 PM
let me try this again with the attachments....
04-06-2024 03:00 PM
I have attached to VI...hopefully this time it will stay attached.....
04-06-2024 03:05 PM
Here is the H file Labview generated.....
04-06-2024 03:45 PM - edited 04-06-2024 04:35 PM
You're certainly trying to make this quite complicated. First mix and match C array pointers and LabVIEW array handles. While that is not invalid, it is for sure making things not easier, especially if you don't have a lot of C programming experience.
There is nothing wrong with that DLL but there is a lot that could be wrong in how you call this function in C or Python. Nothing LabVIEW could help you with.
While calling this from C is not really very complicated, at least if you know about C programming and the fact that LabVIEW array handles are not simply C pointers but specific LabVIEW objects that need to be allocated, resized and de-allocated with the according LabVIEW memory manager functions. Luckily, LabVIEW also adds exports to your DLL that are specifically meant to do these things for the array types used in your DLL interface.
DoubleArray __cdecl AllocateDoubleArray (int32 elmtCount);
MgErr __cdecl ResizeDoubleArray (DoubleArray *hdlPtr, int32 elmtCount);
MgErr __cdecl DeAllocateDoubleArray (DoubleArray *hdlPtr);
You have to use these functions to deal with every single DoubleArray data element in your API. A little convinience trick is that you can pass in the according cluster containing these array handles with a NULL pointer value for each, and the LabVIEW DLL will then allocate a valid handle if necessary.
When you want to interface to this DLL from Python things get immediately a lot more nasty.You have to setup the interface using ctypes and that needs to be done in a way that is perfect. If not done perfect you get at best nothing, but much more likely crashes. And in order to do that perfect you need to know in fact even more about C programming than what you would need when calling this from C. Because you need to configure the Cluster struct for instance perfectly and while the C compiler does the exact memory layout automatically right based on the declaration in the header file, there is no such thing in Python ctypes. You have to build/define it yourself.
Also accessing a handle in C is fairly straightforward as you can simply double reference the handle to get at the actual data in the handle. But in Python things get also more complicated. Your DoubleArray handle in Python is really something like
class DoubleArrayRec(Structure)
_pack_ = 1
_fields_ = [("dimSize", c_int),
("elm", c_double * 1000)]
DoubleArrayPtr = POINTER(DoubleArrayRec)
DoubleArrayHdl = POINTER(DoubleArrayPtr)
But of course things are actually more complicated than this.
First, LabVIEW 32-bit uses byte packing so you need to add a pack attribute to the Structure class definition when you use 32-bit DLL and Python. But in 64-bit this is not only unnecessary but wrong.
Python ctypes does not have OOR (original object return) datatypes, this means you can not simply declare a Python type and hope to use it to lay over an external value like that. So basically trying to access LabVIEW handles from Python is going to be a very tricky thing. I can't recommend to try it. It would be better to define these as extra function parameters and as array pointers too, and preallocate them in Python to the right number of elements before calling the function. That way you avoid most of the memory management hassles that you always get when calling managed environments such as LabVIEW from another differently managed environment such as Python.
04-06-2024 06:32 PM
The question relates to how to evaluate the output arrays and properly assign the start address and length of the arrays from the DLL so that C can properly allocate the proper memory.
In my application you can see from the VI that I am generating arrays using Labview and the Filter Routines for interpolated FIR filters (linear phase).
THe issue that I'm having is that I don't if I'm setting up the DLL correctly and how best to ensure the subsequent C code that will be calling this dll, external from labview, can process the arrays properly.
Any assistance you can provide would be appreciated as I am new to DLLs and the requirements C has to properly allocate the start address, memory space, and ensure the space is not over written.
THANK YOU!
04-06-2024 06:56 PM
OK, lets make this easier for me. Lets talk about what is needed to take the dll H file generated by labview, output only 1D double precision numeri's (NO CLUSTERS) and get the C code to be able to read the arrays generated by the Labview DLL.
IT sounds like Labview is generating the proper DLL so the underlying question I have is how do I take this labview generated DLL and have C properly read the arrays an properly allocate the required memory size and address for the data.
THANK YOU !
04-06-2024 07:05 PM
For clarification: I'll ensure the DLL is only dealing with 1D 64bit double precision numbers. No Clusters. No Python.
After I generate the DLL, what is the proper code needed to get C to properly allocate memory, proper size, and start address to allow me to read the 1D array. The input size of the array is always smaller than the output size of the array due to the IFIR delay caused by the number of samples it takes to fill the Z-1 terms and provide valid output data. As you can see from the VI the length of the array on the output of the IFIR filter is longer than the array entering the IFIR Filter.
If I am annoying you due to my limited knowledge in this space forgive me.