04-13-2018 05:39 AM
As to what can be configured in Call Library Node - there is not much that can be configured:
And nevertheless - the wrapper dll works when the IR API function is commented out - so they have made something wrong there. The Testo support team says that this is a Labview problem.
04-13-2018 05:59 AM
@igorbounov wrote:
And nevertheless - the wrapper dll works when the IR API function is commented out - so they have made something wrong there. The Testo support team says that this is a Labview problem.
Hmm, uncaught exception somewhere in that driver? Your C program doesn't create any exception handler around the function call so unless there is a fatal exception thrown, such as a general protection error, you will never notice!
LabVEIW creates by default an exception handler around DLL calls and that can also be triggered by non-fatal exceptions, such as division by 0 errors. This will be translated into the threaded 1097 error too.
While you can disable this by setting the Error Checking to Disabled in the Error Checking tab, that is not exactly an advisable action.
04-13-2018 06:03 AM
@rolfkIf the function uses cdecl or stdcall calling convention is not defined by this. It is defined either by an explicit __cdecl or __stdcall keyword ...
Here comes the very edge of my dll-building-knowledge. I suppose that by default it should be "__cdecl", though not quite sure, and how it should be done properly - don't know. I've tried this:
__stdcall __declspec(dllexport) int open_image(int *id, char *fname);
And then in the Call library function node in the Function prototype field appeared strange symbols, I've changed the Calling convention field to "stdcall" and tried it using this way - the Labview VI crashed again.
May be when in your wrapper DLL you call some function from another library - you should do something special?
04-13-2018 06:09 AM
@rolfk wrote:
While you can disable this by setting the Error Checking to Disabled in the Error Checking tab, that is not exactly an advisable action.
I've tried this disabling, too - it was an unexpected behaviour, a very impressive one: the whole Labview Framework just exited...
04-13-2018 06:16 AM
Considering that this does stretch your DLL building knowledge, it really does not help that you try to do this with GCC. GCC never was the most advisable tool to create DLLs. While it works great for Linux and just about any other OS, there always have been some struggles between the GCC developers and Microsoft. Some projects like MinGW spent a lot of effort to teach GCC to be more Microsoft friendly and build toolchains based on that which could be used for development on Windows. And GCC sometimes imported some of the features from those projects, but not every one and not always completely because of license issues, politics or some personal grudge of some people.
Pure GCC is pretty Microsoft compatible nowadays, albeit it can be a challenge to find the according GCC settings that persuade it to create fully Windows compatible code, but unfortunately the compiler and linker are just a small part of a complete development toolchain and here Microsoft Windows always has been a moving target to tackle. Microsoft is big enough to change something and if it does't work with third party tools like GCC anymore show you the finger and say: bad luck!.
04-13-2018 06:29 AM - edited 04-13-2018 06:31 AM
@rolfk wrote:
GCC never was the most advisable tool to create DLLs.
Never mind: I've built this very wrapper DLL on Microsoft VC++ express - with the same result. It works when called from a C++ programm (MinGW - it simpler for me, VC++ is such a mess...) and crashes when in the Labview VI.
There should be something simple that I miss - or users would have run away from Labview.
As for me - I'm starting to regret for sticking to LV. It looks like the project would be simpler and flexier were it done in an old good GCC + GTK++.
04-13-2018 07:26 AM
What about this?
04-13-2018 07:48 AM
Mmm, it looks like a locomotive - just as complicated and all brilliant, but, hm, "error 1097".
I've put the full Testo IR API library set here (https://www.dropbox.com/s/jurowxitqi9u6xb/ir_api.zip?dl=0).
For a while.
There is a "collateral damage" when a "testo_irimage_open" function is called successfully: it creates a copy of infrared part of image in a local user temporary directory - I've found there a lot of such pictures. Now I can count how many times I've launched the test C++ application.
May be an effort to create that file crashes Labview?
And, next, how does Labview find all other libraries from Testo IR API? Now I do run the open_irimage.vi from a directory where lay all those dll - there is more than 60 files. Where actually is Labview VI is executing?
04-13-2018 08:07 AM
Here is result of test run in a screenshot.
04-13-2018 08:08 AM - edited 04-13-2018 08:19 AM
Ahhh now we are getting to the crux of the problem!
LabVIEW is not locating any DLL besides the one you link in the Call Library Node. It can not even start to guess properly what other DLLs need to be loaded. For statically linked DLLs in the DLL that you call from the Call Library Node, Windows is supposed to find them and link them. If that fails then you would get an according error message from LabVIEW that loading of the main DLL that you linked to in the Call Library Node has failed, as Windows will fail the load request when it can't find any of the static dependency DLLs.
But there is more: The DLL can also link in delay loaded DLLs, that are DLLs that are defined to only get loaded when one of its functions is called for the first time. It may crash here. Or the DLL does its own dynamic loading of submodules depending on some runtime parameter and fails to specify a correct path to Windows where to load that DLL from and also fails to handle possible errors that can occur from trying to load a DLL dynamically, which could crash too.
Now when Windows tries to load a DLL whose name is not a fully qualified name, it will look in a few standard locations only. The first one after checking that the DLL is not already loaded, is in the application directory (where your test.exe program resides).If you copy all the DLL shenigan of this package into your exe directory then yes I can understand that you won't see any errors in the simple test executable.
But LabVIEW is an exe too, but its installed into the Program Files directory. So it's not like people are going to put random DLLs into the LabVIEW folder to make things work, yet that is what Windows expects when a DLL does very simplistic dependency handling.
And no, aside from a quick and dirty test to see if this might be the problem you SHOULD NOT put DLLs into the LabVIEW directory! If you do so for testing, throw them immediately away again after.
If you see that it is something with this, then alas, the package is simply broken, despite claims of the manufacturer to the contrary. It will also break in other environments that are not just creating standard exe files to run, including Python, and many more. It's not from this time to require an application developer to put all dependent DLLs into the exe directory. If you load modules dynamically you need to implement some smarter strategy to locate them, than just hoping that Windows will resolve them anyway.
There are probably really two problems here. Somewhere one or more of the DLLs uses dynamic loading of other modules but doesn't specify some smart fallback mechanisme to find a DLL elsewhere when it fails. And more seriously even, somewhere in the code some code path uses resources (function pointers or similar) that were supposed to be loaded dynamically without checking that this loading was successful.