07-25-2012 12:01 PM - edited 07-25-2012 12:03 PM
Hi,
I have to call an external DLL from LabVIEW but I have the following issue. One one of the other forum posts, this issue, I think, had been addressed, by I guess editing the DLL itself, or maybe I did not understand the solution right. But I do not have access to the DLL code. I just have the header which has a function definition with char **.
The "Import DLL" functionality of LabVIEW is mistaking char** for a string, and so I cannot use that too. If I wire a string to the input, then the DLL throws an exception giving Error 1097.
Calling convention is C.
The header file has the following function definition:
DWORD Send(DWORD args, char ** strng)
So I think the DLL expects an array of Strings. I tried the Type: Array of "8 bit unsigned integers" using "Array Handle" in Call Library Function Node, which led to the following preview:
uint32_t Send(uint32_t args, Array1DUint8_t **strng);
Thus I give one string , and convert the characters to 8 bit unsigned array and LabVIEW code looks as shown as below: (Instead of Array of Strings). The input "1" is number of arguments/strings.
This code runs without error 1097. But my DLL reads the string as random symbols. One example is shown as:
I do not know why my DLL is reading random things from memory. I am pretty sure its expecting pointer to pointer of character, and may be LabVIEW is giving something different.
I also tried an array of strings, and used "Adapt to type" in the CLN, but then the output changes from random characters to some number. (Like x5bc087305bc003b5.....
Any help will be appreciated.
Also, I have come across posts which say I have to write an external wrapper. I do not want to do anything outside the LabVIEW environment as far as possible, and moreover have almost zero experience in writing one. Thus if a solution in LabVIEW exists, then it would be optimum.
Thanks.
07-25-2012 12:27 PM - edited 07-25-2012 12:28 PM
You need to know what the DLL expects here: a pointer to a single string, an array of pointers to strings, or something else? Is the "strng" value an input, an output, or both? Without an understanding of the function call requirements it's not possible to provide specific advice. However, it is most likely possible to get this working in LabVIEW. You will probably need to use DSNewPtr, MoveBlock, and DSDisposePtr. These are all memory manager functions that you can call from a Call Library Function Node by setting the library name to "LabVIEW" and these functions are documented in the LabVIEW help. They will allow you to get a pointer to a string, or an array of pointers as appropriate. You can find one example of using these functions to generate an array of strings in this thread at LAVA: "Passing array of string to C dll."
07-25-2012 01:08 PM
Hi nathand,
An example call to the DLL using text coding looks like this: (and it works)
---------------------------------------
char *sendstring[2] = { “TestString”, “A”};
DWORD argsno = 2;
Send(argsno, sendstring);
-----------
And its an input only.
Does this info help?
Thanks.
07-25-2012 01:25 PM
The discussion to which I linked demonstrates exactly this situation. Here's the code from that post (I'm the one who posted it there, so I'm not copying someone else's work). This is a "snippet" - you can drag it directly into a block diagram (with some web browsers you may need to drag it to the desktop first, then drag it from there into the VI).
07-25-2012 01:28 PM
Thank you nathand, I will try this out , and update you about my findings!
But your post instills a lot of confidence in the solution working, and thanks for that!
07-25-2012 02:05 PM
Hi nathand!
the solution works!
Thanks a lot. Now I will spend some time and try and figure out whats happening there, and if I have some questions, I hope I can ask you.
Anyways, sometimes I end up getting the screen below, after succesful execution of the VI. Any ideas why? I have attached my CLN replacement, in case that could be a source. Thanks.
07-25-2012 02:12 PM
I don't know anything about that error and your screenshot reveals nothing about the configuration of the library call. I recommend setting the Error Checking level for your call to the DLL (in the Call Library Function Node setup) to "Maximum" and see if any errors appear. Is it possible there's an error in DLL and it's doing something it should not do with the memory?
07-25-2012 02:18 PM
Oh sorry, here is a snapshot of the config, and I am pretty sure there is no problem with that
Anyway I have no access to DLL nor to the people who coded it, so I have no idea how it handles memory.
I will try figuring out the reason for the crash. Mostly the crash occurs when I hit "save".
But thanks for your help!
07-25-2012 03:21 PM
It's possible the DLL is holding on to the memory after the function call - do you call any functions from that DLL later in your code, or does the DLL do anything in the background? If the DLL is still trying to use that memory after you call DSDisposePtr, you could have memory corruption issues. Maybe try moving DSDisposePtr to the very end of the VI?