Jump to content

Debug or Release DLLs for LabVIEW in C using Microsoft Visual Studio


Recommended Posts

Dear all,

this is quite a general question about DLLs created in MS Visual Studio and the effects of building the DLL under Debug or Release.

I'm not so much trying to solve a specific case, with specific details, more to generally understand something of the full set of rigorous steps necessary to guarantee that at least a LabVIEW VI sitting on a windows machine (running Windows XP) will be happy to load a DLL.

I find that for very simple DLLs (such as the example C code included at the end of this text)

LabVIEW v 8.2 on some machines is happy to load the DLL and run it whether I build it under Debug or Release

whereas on another machine

ostensibly running the same version of XP and also LabVIEW v8.2

the Debug version of DLL will be rejected by the (same) VI with the message (when exiting the DLL configuration dialog - after right click on the DLL icon on VI diagram)

Error loading "C:\blah_blah_debug.dll". This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.

whereas the Release version of the DLL will be accepted and will run.

This was particularly confusing, because in previous experience of using (admittedly much larger DLLs which usually include other code from static .lib files written by other people - or myself) on yet a third PC, labview has often rejected a Release version of a DLL and yet has apparently been happy with a Debug version.

The Release version on such occasions is rejected with the following message (during VI running)

Error 13 occurred at dll_name.dll

Possible reason(s)

LabVIEW: File is not a resource file

I had a look at the DLL documentation for LabVIEW and it mentions compiling and building under both Debug and Release so I don't understand enough about

what actually happens under the bonnet (hood in US speak) to know what to do about it.

I have heard a lot of mythological possiblities so some concrete knowledge from experts would be very useful.

Some points for guidance:

I always write in pure C, no C++ anywhere in my code.

I therefore do not not use extern "C" statements - since I am compiling the code with the Visual Studio option "compile as C (/TC)" switched on in all cases.

I use the _stdcall convention with the __declspec(dllexport) token

I do not use DEF files (this might be my downfall - but according to what I've read I shouldn't need a DEF file if I use __declspec(dllexport) )

Any similar experiences?

Help appreciated

Below are the simple example .c file followed by the .h file

#include"DLL_test.h"

EXPORT_DLL int testFunction(int *value_in_out, int value_to_add) {

int in = value_in_out[0];

value_in_out[0] = in + value_to_add;

return 0;

}

with a header file like this

#ifndef __DLL_TESTING_NOV_08_TOKEN_

#define __DLL_TESTING_NOV_08_TOKEN_

#define EXPORT_DLL __declspec(dllexport)

EXPORT_DLL int testFunction(int *value_in_out, int value_to_add);

#endif

Link to comment

Every time I've encountered this error message

"Error loading "C:\blah_blah_debug.dll". This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem."

It has been when a DLL was built with the debug switch on and is linking to the debug version of a Microsoft run-time DLL. In your case, you're probably using msvcrtd.lib which links to the msvcrXXd.dll, where XX is the version (80 is typical). The msvcrXXd.dll is not part of the standard windows install where the msvcrXX.dll, which is linked to by the msvcrt.lib, is - that's why the release version runs and the debug doesn't. Make sure you're not using a /MDd compiler switch (the default release build does not but the Debug build does).

I've found this app

http://www.dependencywalker.com/

to be pretty useful in discovering which run-time component is missing when a DLL won't load.

As far as

"Error 13 occurred at dll_name.dll

Possible reason(s)

LabVIEW: File is not a resource file"

I don't know - I don't have any experience with this error message in the context of loading a dll - I have seen it in other circumstances but none seem related to your case.

Mark

Link to comment

QUOTE (mesmith @ Nov 24 2008, 07:14 PM)

As far as

"Error 13 occurred at dll_name.dll

Possible reason(s)

LabVIEW: File is not a resource file"

I don't know - I don't have any experience with this error message in the context of loading a dll - I have seen it in other circumstances but none seem related to your case.

Mark

Mark is completely right in all he says. The debug versions of the MSVC runtime libraries only get installed when you install Visual C or maybe an application with MSVC runtime support compiled in debug mode, although I'm not sure the debug version of the runtime libraries really belong to the redistributable part of Visual C, so such an application if not from yourself may be not legal.

It's most likely a somewhat misleading error message in the shared library loader. LabVIEW has had traditionally a certain number of well known error codes. When adding a new subsystem the developer always had two choices: Adding a new error code for every situation or trying to find an existing one that matches the situation fairly well. Adding new error codes used to be a major hassle since all the necessary information had to be entered into the resource files of LabVIEW too which is a completely different work flow chain than editing the C source code, so the choice was usually towards reusing an existing error code.

When LabVIEW asks Windows to load a DLL on its behalf Windows will fail the loading if a dependency can't be satisfied. The returned error code is sort of generic and there is virtually no way to get the information about what dependency was missing unless one would walk the entire import tables of the DLL and its dependencies.

Translating OS specific errors into Framework specific errors is always a tricky and lossy business.

Nowadays the errors are not as tight into the LabVIEW Framework itself so the choice is more often made to add subsystem specific error code ranges but the Call Library Node shared library loader code dates back to LabVIEW 3 and at that time priorities and possibilities were quite different.

Rolf Kalbermatter

Link to comment

QUOTE

I've found this app

http://www.dependencywalker.com/

to be pretty useful in discovering which run-time component is missing when a DLL won't load.

Mark

:oops: - I realised I'd made one mistake - I was not using __stdcall at all (don't know where I got that idea from) that should have been __cdecl

Thanks for the explanation of the underlying mechanics, that makes things a lot clearer.

Also the dependency walker proved to offer essential feedback. I could fiddle with Visual Studio and through trial and error was able to get DLLs which work in release mode. :thumbup:

As I was also including some code from static libraries that I had built, there may have been some effect from these in some cases too - complicating the picture.

(obviously not in the simple example case above which was not working)

For reference I summarise here those Visual Studio settings which make everything work in Release mode, in the hope that it helps others similarly stuck

Assuming:

  • You have code which you first build into static libraries which will then be used by the DLL you ultimately wish to create
  • You are using MS Visual Studio 2005

For static libraries (which one might have anyway) and later incorporate into DLLs

  • Set run time library to Multi-Threaded (Properties:C/C++:Code Generation:Runtime library) to Multi-Threaded (/MT)
  • Set calling convention (Properties:C/C++:Advanced:Calling convention) to __cdecl(/Gd)
  • Embed Manifest (this ensures standard windows bits are present) (Properties:Manifest Tool:Input and Output:Embed Manifest) to YES

For DLL projects a similar set of settings were applied

  • Set run time library to Multi-Threaded DLL (Properties:C/C++:Code Generation:Runtime library) to Multi-Threaded DLL (/MD)
  • Set calling convention (Properties:C/C++:Advanced:Calling convention) to __cdecl(/Gd)
  • Make sure linker generates manifest (Linker:Manifest File:Generated Manifest) to Yes
  • Embed Manifest (this ensures standard windows bits are present) (Properties:Manifest Tool:Input and Output:Embed Manifest) to YES
  • Enable incremental linking (Properties:Linker:General:Enable incremental linking)Yes(/INCREMENTAL)

I had a few other settings but I believe these are optional (and specific to what I wanted) and probably nothing to do with fixing my earlier problems, included in case they are relevant

  • Build in Release mode
  • (optional) Switch off 64 bit issues warning (Properties:C/C++:General:Detect 64-bit Portability issues) to No
  • (If you are using maths library constants like M_PI) add preprocessor definition (Properties:C/C++:Preprocessor:Preprocessor Definitions) _USE_MATH_DEFINES
  • Set optimization (Properties:C/C++:Optimization:Optimization) to Maximise speed (/O2)
  • Set optimization (Properties:C/C++:Optimization:Favor Speed or size) to Favor speed (/Ot)
  • Set optimization (Properties:C/C++:Optimization:Whole program optimization) to No
  • Disable C++ exceptions (Properties:C/C++:Code Generation:Enable C++ exceptions) to No
  • Set compile as (Properties:C/C++:Advanced:Compile as) to Compile as C code (/TC)
  • Ensure not using Precompiled Headers (Properties:C/C++:Precompiled Headers:Create/use) to not using...

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.