09-15-2009 03:51 PM
I'm currently trying to work with a supplied DLL.
I have header files and all, and the DLL import wizard does a decent job of importing the DLL functions but there are some data types which simply can't be handled.
The DLL requires usage of a data type which is a struct with value and reference data types. I could theoretically replace the references with simple U32s but much of the required information in the data is in the data structures referenced by the pointers.
How do I go about implementing this seeing how I need to be able to pass the data back into the DLL in its original form (value and reference types).
I have something like the following:
struct Item {
Int Device,
*Item Next
*Item Previous
*Data Datastruct
}
I have downloaded the WDK from Microsoft, have CVI and Visual Studio 2008 available. I'm not very experienced at this end of things... I can deal with Structs with pure value types but how do I get at the data in the reference types?
I strongly suspect I need a wrapper DLL, but how is the best way to go about this?
Shane.
Solved! Go to Solution.
09-22-2009 10:00 AM
Hi Intaris,
In my opinion you will have to write a wrapper.
In this wrapper you can access the Values of the Datstruct like this: (just an example on how it should work)
struct Datastruct //Datastruct is defined in your DLL allready ! Just for example !
{
int integer;
char data;
};
int read_Integer (Datastruct *Data)
{
return Data->integer;
}
Your "Item" Structure contains three pointers in doubly-linked-list style.
Maybe it could help if you can post the functions you would like to use from this DLL.
If one of your pointers gets corrupt, the doubly linked list is lost. So be carefull. Maybe you have to wrap more functions to get rid of the"previous" and "next" pointers within labview.
Best regards,
Balze
09-22-2009 10:18 AM
I kind of knew I would have to write a wrapper, but my question was how to best go about it.
I need to be able to pass the ENTIRE structure into certain functions in the DLL so I was thinking along following lines....
Operate within classes - keeps pointers read-only and prevents unwanted surprises
Convert Linked List to Array for outputting to LV (Array of clusters with all referenced elements stored by value)
Output the struct as a binary blob to LV (Size constant hopefully) to store so that it can be used as an input for the other function. This blob will be invisible outside of the class.
The entire structure is actually read-only but it contains important infpomation. Does this sound plausible?
Shane.
09-22-2009 10:57 AM
Hi Shane,
To be honest, I don't understand why you have to pass the ENTIRE structue (if it's "Item" structure. The pointer to the next and the previous item should be held and manituplated in the DLL, doesn't it?
Operate within classes....
Are you talking about Labview Classes? I didn't use it yet. Sorry.
Convert Linked List to Array You can't store all elements by value in a cluster, because it's kind of recursive. The next pointer leads to the same Item structure (with it's own next pointer. If it's a circulary-linked-list it will never stop)
Or did you mean to store the pointers as a U32 value? That should work.
Output the struct as a binary blob Yes, why not ! But that lets me assume you don't know the concrete "Datastructure" ?!
I'm honest again I can't see the important information you mentioned if you pass the Data structure as a binary blob.
Read-only is a very good idea. If you don't need to tweak the pointers in the list you should avoid it.
Balze
09-22-2009 11:01 AM
The dea of passing the entire structure means that I can call the native functions from LV thus cutting down on the nr of wrapper functions I need. I don't need to know what the pointers are pointing to, just pass the pointers.
Converting a LL to an array...Let's just sayI'm pretty confident can do that. I'm aware it wraps,but that's easily dealt with.
Again, the Binary blob is just being used so that I only need wrapper functions in one direction. From LV to DLL can simply pass the bloba nd be done with it. I would rather create work in LV than in the DLL. I don't do many DLLs.
Shane.
09-22-2009 12:00 PM
Understand.
Then you should try what you mentioned.
My way would be to implement a wrapper for all used function (how many will there be for a LL ?)
In my opinion it's easier to handle from LV.
Balze
09-22-2009 01:53 PM
One of my problems is understanding the scope of data within a DLL.
If I store values in variables which are accessible from different DLL calls, are the values retained between calls? When is the code for the DLL initialised and when is it uninitialised?
I know what's going on in LV but I'm never quite sure with a DLL......
Shane
09-23-2009 12:36 AM
Shane,
that's allways a problem when using a DLL.
If you don't have the sources of the DLL you have to trust the description of it.
(Or you have to disassemble to be sure, what is prohibited in most cases )
If (in your case) the linked-list is manipulated from somewhere else than your Labview Code you will get in trouble.(Items inserted, deleted or changed)
I don't know your DLL. But normally data is stored inside the DLL. For example I've got a DLL function which reads a counter from a DAQ hardware. If i don't reset it (On of its parameters is reset), it sends back the nuber of counted events. This DLL has not to be initalized.
Other DAQ hardware i use needs to be initalized using its DLL prior to reading any values.
All this depends on the implementaion of your DLL.
Do you have a detailed description of your DLL?
Balze
09-23-2009 03:40 AM
I'm in a good position in that the DLL has the full source code available. It's a FOSS project.
Being a little less than an expert outside of LV, this unfortunately doesn't really help me.
The linked list is a hardware list which can be changed whenever hardware is removed or added (USB).
I suppose I'lljust have to implement a few functions and see how it goes.
Thanks for the help
Shane.
09-24-2009 10:06 AM
I'm fighting with CVI at the moment to get a DLL up and running and came across the following example code...
for (bus = busses; bus; bus = bus->next) {
struct usb_device *dev;
for (dev = bus->devices; dev; dev = dev->next) {
/* Check if this device is a printer */
if (dev->descriptor.bDeviceClass == 7) {
/* Open the device, claim the interface and do your processing */
... }
Does this not mean the LL is NULL-terminated instead of wrapping around?
Shane.