05-23-2010 10:13 AM
I reckon this has probably been dealth with before, but I tried searching and didn't find an answer which solved my problem.
I have a function implemented in a DLL which returns a pointer to an incomplete struct. All working fine.
I now want to write a function which passes an array to the DLL (pre-allocated in LV) and fills this array with a series of pointers to the incomplete struct (Same datatype as works fine above).
I cannot get this to work.
I have tried:
int function(struct incompletestruct *array) as a function prototype, but I get complaints of "unknown size of incomplete struct" if I then try to reference array[value].
I have tried
int function(struct incompletestruct *array[]) as a function prototype, but LV locks up hard when I call this with "pointer to Array data" setting.
I have tried
int function (struct incompletestruct *array[16]) as a funtion prototype, but same lockup as above.
What combination of function prototype and DLL calling convention in LV do I need for this?
I'm using LV 2009 SP1 and CVI 9.0.
Shane
Solved! Go to Solution.
05-24-2010 02:43 AM
Does anybody have some SENSIBLE suggestions?
Shane
05-25-2010 02:14 AM
OK, now that the spambot reply is removed, I come accross all silly with my "SENSIBLE" comment... ![]()
I would be very grateful for help on this issue.
I want to return a reference of all USB devices found in the system via LibUSB and while my function works for a single element (giving the reference as return type) I cannot find a way to work with an array of these items. Since I cannot pass back an array as a return value, I need to pass a pre-initiialised array to the DLL.
How do I pass an array to a DLL where the DLL expects an array of references? How do I handle this array in the DLL? I tried Array[] which compiles but locks LV up on me when I try to call it. Do I need to go the **Array route? I'm a bit of a CVI newb, so I'm not going to be annoyed if somebody points out some incredibly stupid thing I'm doing.....
Regards
Shane.
05-25-2010 03:59 AM
I'm not able to solve the complete issue, but can at least give some hints:
* an array of pointers is an array of I32 (I guess that won't be true in 64bit any more).
* Hidden in the LabVIEW.exe there are some undocumented functions that allow to do pointer operations. Somewhere there should be a LabVIEW.h file. And just type labview as the dll-name in the call library node.
* So the complete concept would be to cast data-pointer via these build-in functions and treat the pointers as I32 to pass them inside LV.
Felix
05-25-2010 04:26 AM
Thanks Felix,
The Pointer-I32 bit I already know. I am able to receive and return a pointer to a single object I am looking for. It's only with arrays I have trouble.
The I32 values are opaque in LabVIEW. I can't use them outside of the DLL, but I need tobe able to decide with LV which device is being called where and when. As such I read the I32 from the DLL and pass it back in whenever I need it. The I32 is not modified or otherwise used in any way in LV.
Something occurred to me this morning.... I have had problems in the past with trying to open a reference to perticular devices.. I might be causing the lock-up by opening references to the wrong devices in my system, the lockups may not be a direct effect of my assumed array problems. In my testing, I have been trying to open references to ALL devices and this is sometimes not a good idea.
I'll give an update later.
Shane.
05-25-2010 08:36 AM - edited 05-25-2010 08:38 AM
Aargh.
This is why I love LabVIEW. The bug I had in my code would NOT have gotten past my eyes in LabVIEW.
The device I should not be opening a reference to (Don't ask me why, it is just like that...) is the first on the list of my LibUSB devices.
I tried to use a special VID and PID code to simply return EVERYTHING (0xFFFF) and this is where the bug crept in.
Using the code
if ((dev->vid == VID) || (VID = 0xFFFF))
Do something
will always try to open a reference to EVERY device.
The correct code:
if ((dev->vid == VID) || (VID == 0xFFFF))
Do something
behaves itself properly.
Bah!
Felix,
thanks for your help anyway. Sometimes just hearing someone answer kicks the brain into a different gear which ends up solving the problem. As such, even though your post doesn't contain the technical solution, it's getting marked as having solved my problem....
Shane.
05-26-2010 01:50 AM
Intaris wrote:
if ((dev->vid == VID) || (VID = 0xFFFF))
Do something
will always try to open a reference to EVERY device.
The correct code:
if ((dev->vid == VID) || (VID == 0xFFFF))
Do something
behaves itself properly.
That is why some C programmers reverse the comparison parameters:
if ((dev->vid == VID) || (0xFFFF = VID))
would have given you a nice compilation error to the meaning of "operand is not a lvalue" or similar.
05-26-2010 03:32 AM
Rolf,
that's a cool idea. I've never heard of that before. I must remember to do this, it makes catching problems like this SOO much easier.
I have my code up and running now. I didn't get the array part working but I simply added an "index" value to my single-device code so that I can target different devices to open a handle to.
I'll get back to the array version sometime and will post if I get it working.
Thanks for the help.
Shane.