01-09-2020 04:47 AM
Hi all,
I have a simple LabVIEW VI that outputs the application directory path.Now I have created a DLL of this VI in LabVIEW. When I use this DLL in LabVIEW, it doesn't work.I have attached the VI, DLL folder and the DLL TestBench VI for reference.
Any kind of help is highly appreciated.
Thanks in advance.
Solved! Go to Solution.
01-09-2020 05:43 AM - edited 01-09-2020 05:44 AM
You configured the DLL function to return the path by reference:
void __cdecl ReturnApplicationDirectoryPath(Path *ApplicationDirectory);
But in your test VI in the Call Library Node you configured the parameter as: Adapt to Type, Pass: Handles by Value.
A LabVIEW path is a handle, just as strings and arrays are too, so the Pass: Handle by Value applies to them too. Change that to Pass: Pointer to Value and you are good.
That said working with such paths from inside a DLL is tricky at best. It seems to return the directory the DLL is located in for some interesting reason but that wouldn't be what I had expected. The online help isn't fully clear either. There is a change that the VI might return the path of the application itself rather than the DLL when you use it inside a build application.
01-09-2020 06:13 AM
If you want the path of a dll, you should be able to use LoadLibraryA, GetModuleFileNameA and FreeLibrary.
01-09-2020 06:15 AM
Thanks rolfk. It is working.
Just needed one more favor from you.Can u explain me the different data formats (Handles by value,Pointers to Handles, Array Data Pointer and Interface to Data) for a parameter. Or maybe you can post a link where it is explained in details.
I don't have much of a programming background, so these are not very clear to me.
Thank u again.Your help was indeed really helpful.
01-09-2020 06:59 AM
Well, Paths are a little special as NI does not document the internal data format of the handle. So from the four possible selection only Handle by Value and Pointer to Handle are meaningful. It's basically simply about what part of the handle is passed to the function. Of course not having any C programming experience makes the use of the Call Library Node a difficult exercise (and in my opinion a very dangerous too).
You can very easily crash your software but what I find even more dangerous is the fact that it may seem to work but in fact corrupt memory anyhow if you somehow don't match the Call Library Node exactly with what the DLL function expects. There is no safeguard and hand holding for you. The configuration has to be made to match the DLL function declaration by YOU and without understanding C pointers and such you are basically playing with dangerous fireworks.
typedef struct
{
int32 size;
uChar elm[1];
} LStrChar, *LStrPtr, **LStrHandle;
Handle by Value:
/* LabVIEW passes the handle to the function. */
void MyFunction(LStrHandle string);
Pointer to Handle:
/* LabVIEW passes a reference to the handle to the function. */
void MyFunction(LStrHandle *string);
Data Pointer:
/* LabVIEW passes the pointer to the elm[0] inside the handle to the function. */
void MyFunction(char *string);
Interface Data:
/* LabVIEW passes an interface pointer to the handle to the function. This is a rather esoteric option that I have never ever used and also don't think is useful except for some strange NI internal software uses. It uses an ActiveX type interface data pointer but in a way that seems valid in all LabVIEW platforms, so it is not really ActiveX but just functionally equivalent. Definitely nothing you will ever use. */
void MyFunction(ILVData **arg1);
01-09-2020 11:19 PM
Thanks Rolfk.
Keep up the good work.