11-19-2011 12:53 AM
I'm having some difficulties calling a DLL from LabVIEW. Here are some things I've tried:
Attempt 1: Put down a Call Function Library node and passed it the DLL path, function name, and function parameters, in accordance with this function. Result is that I get a Error 15, "Resource not found". It doesn't matter whether I'm using C or stdcall. I know my prototype is right based on the dllexp.exe app I've included.
Attempt 2: I try using Tools > Import > Shared library. I point it at "KMotionDLL.dll" and "KMotionDLL.h", and give it the KFLOP path as an include path. The result I get is empty and says "The Import Shared Library tool cannot get exported function names from the input shared library file".
Attempt 3: I do the same import process, but this time I use "KMotionDLL - modified.h". This gives me the same result. I also tried it without the extern statement, same result.
Is there any way to interface with this DLL and access the functions described in the link above? I've attached my code.
Thanks.
11-19-2011 03:16 AM
Two things:
1) This DLL links explicitedly to the FTD2XX.DLL. This is the Future Technology RS-232 USB chip driver. If this driver is not installed in a place where Windows can locate it, Windows will refuse to allow any application to load this DLL.
2) The DLL exports C++ decorated names only. While this makes the use of the DLL through the Call Library Node not really impossible, it is for sure an unneccessary hassle. Talk to the developer and tell him to add the extern "C" declaration to all standard function exports.
11-19-2011 04:31 PM - edited 11-19-2011 04:33 PM
Thanks. The usb driver is definitely there, because a different program works fine using the dll. So what you're telling me is that I need to try to contact the developer and get extern C statements in front of the functions I want to use, because LabVIEW can't use a C++ calling convention. I will work on that.
Is there another workaround possible in case the developer is slow or unwilling to change it?
(if there is a workaround could you put it in your post above so that I can accept just one post as the solution?)
11-19-2011 04:57 PM
Hi,
You can use
"dumpbin /exports whatever.dll"
to get the function names in dll, if you don't want to use a wrapper function or recompile the library.
More written here. This is for C#, but the idea is the same.
Regards,
Michael.
11-20-2011 02:26 AM - edited 11-20-2011 02:29 AM
@Jason Harrigan wrote:
Thanks. The usb driver is definitely there, because a different program works fine using the dll. So what you're telling me is that I need to try to contact the developer and get extern C statements in front of the functions I want to use, because LabVIEW can't use a C++ calling convention. I will work on that.
Is there another workaround possible in case the developer is slow or unwilling to change it?
(if there is a workaround could you put it in your post above so that I can accept just one post as the solution?)
Another application may work because it has the FTD2XX.DLL in its executable directory. Windows will search the directory where the executable image for the current process is located for any dependencies too. Otherwise the DLL needs to be located in the Windows. or System directory or any of the directories in the PATH environment variable. And the Windows and System directories get extra complicated if you have a 64 Bit OS version. In the case of LabVIEW if you want to use private dependent DLLs (DLLs not located in Windows, System or PATH locations and not directly referenced through a Call Library Node) you can place them in the directory where LabVIEW.exe is located. I believe the directory where the project file is located should work too. In the built executable you have to make sure that the DLL is copied into the same directory as your built executable.
Decorated names don't make it impossible to call those functions in LabVIEW as long as they are not using object references as parameter. They simply make it very inconvinient.
11-20-2011 02:56 AM - edited 11-20-2011 02:57 AM
I placed ftd2xx.dll in my windows directory and also the labview.exe directory and I still get the "Resource not found" message. (I attached ftd2xx.dll.)
At this point my understanding is that the reason I'm getting the error message is that I'm trying to call a function named "WriteLine" in the dll, but in reality since the dll was compiled in C++ it will have a different name. Using the dllexp.exe I included in my original attachment I get the export information as:
| Function Name | Address | Relative Address | Ordinal | Filename | Full Path | Type |
|---|---|---|---|---|---|---|
| public: int __thiscall CKMotionDLL_Direct::WriteLine(int,char const *) | 0x10007940 | 0x00007940 | 47 (0x2f) | KMotionDLL.dll | C:\Users\jharriga\Desktop\KFLOP\KMotionDLL.dll | Exported Function |
I tried calling "CKMotionDLL_Direct::WriteLine" instead of "WriteLine" but that didn't work. Will the dumpbin/export command give me a different name which I can use instead? I don't have visual studio installed on my machine, but I can get it installed on monday if need be.
One thing is however, when I open up one of the dll examples that comes with labview and change the function name inside of it, the vi breaks and says "Function not found in library". In my case the error message is at runtime.
11-20-2011 03:27 AM
Ok, I made some progress!
I downloaded Dependency Walker, located here, visual studio not required: http://www.dependencywalker.com/
I opened up my dll with it and clicked on the top level in the hiearchy. I right-clicked on the function names and selected undecorate. I scrolled the the disired function name which was this:
int CKMotionDLL::WriteLine(int,char const *)
I then right-clicked and un-checked undecorate, to show the raw name, given here:
?WriteLine@CKMotionDLL@@QAEHHPBD@Z
I ran it and got an error message from what appeared to be the dll, not labview, then labview crashed the first time. Subsequent calls give "LabVIEW: An exception occurred within the external code called by a Call Library Function Node. The exception might have corrupted the LabVIEW memory. Save any work to a new location and restart LabVIEW."
So I'm almost there. I attached the updated vi.
11-20-2011 03:43 AM - edited 11-20-2011 03:43 AM
Ok, I've got two name entries, which one do I want:
int CKMotionDLL::WriteLine(int,char const *)
int CKMotionDLL_Direct::WriteLine(int,char const *)
11-20-2011 04:46 PM
@Jason Harrigan wrote:
Ok, I've got two name entries, which one do I want:
int CKMotionDLL::WriteLine(int,char const *)
int CKMotionDLL_Direct::WriteLine(int,char const *)
This can only the developer of the DLL tell you! As to the VI in the previous post, I don't have 2011 installed on my current machine.
11-20-2011 05:47 PM
Rolf, I've attached a zip that's more complete. In the LV8.6 folder is the vi saved for version 8.6. I've also included the dependency walker program.
I would imagine that since I have the header file, shouldn't I know which functions must be called? The header file makes no mention of "Direct".