Reputation: 61
I am importing an C++ DLL in an Inno Setup install script. The DLL code is as follows:
void __stdcall SetFbParam(
char *dbFileName,char *dbTableName,char *dbParamName,char *dbParamValue) {
// of no use here and doesn't change anything
}
In the Inno Setup, I import it using
procedure FBset(dbFileName,dbTableName,dbParamName,dbParamValue: String;);
external 'SetFbParam@files:MyDll.dll stdcall setuponly';
However, I always get a runtime error during launch of the installer, saying that it cannot import my dll. I tried it with various calling conventions, but it always fails. If it's of any importance, I'm running Win7 x64 with UAC on (the installer requests rights elevation and crashes after that).
The exact message is:
Error
Runtime error (at -1:0):
Cannot import
dll:C:\Users\Nevod\AppData\Local\Temp\is-6LOEC.tmp\MyDll.dll
The dll is there.
Thanks!
Upvotes: 3
Views: 6005
Reputation: 202271
As mentioned in other answers, do not forget to embed all dependencies of your DLL. Though if it is your DLL, better might be to get rid of (or at least reduce) the dependencies.
For example when building C++ DLL in Visual Studio, link the runtime statically, not dynamically.
In project Properties, go to C/C++ > Code Generation > Runtime Library and select Multi-threaded (not DLL).
There are also tools that can embed other external dependencies.
Upvotes: 0
Reputation: 313
In order to use DLLs in Inno Setup's [Code]
section please make sure:
extern "C" __declspec( dllexport )
modifiercdecl
calling convention because stdcall
mangles name (https://learn.microsoft.com/en-us/cpp/cpp/stdcall). Of course it is possible to specify mangled name in Inno Setup import statement. But it seems easier to just use cdecl
.Upvotes: 2
Reputation: 51
(I know it is old but maybe some other hits this one too)
Most probably the name of the function is mangled in the C++ DLL. I had the same problem and I was able to solve it by recompiling the dll. In short:
If you export from C++ something like:
void __stdcall foo()
you will get a function called (Visual Studio):
?foo@@YGXXZ
To prevent name mangling you should use extern "C"
directive. Example (Visual Studio)
extern "C" __declspec( dllexport ) void __stdcall foo()
However I have found that Visual Studio will continue to mangle and you get something like:
_foo@0
The sole way I was able to get clean names is explained here: C++ DLL Export: Decorated/Mangled names
And the culprit is indeed __stdcall
. If you remove that from your declaration:
extern "C" __declspec( dllexport ) void foo()
you will again get a clean export, even without a DEF file. IMO this should be good enough, as the code above declares a "C" exported function and the default calling convention for C is stdcall. However I haven't had the time and disposition to validate this as adding a DEF file is way easier than navigating asm code and check stack pointers :)
Upvotes: 5
Reputation: 81
Is MyDll.dll
32-bit?
Does MyDll.dll
depend on any other DLLs in the same directory? If so, you need to list the name(s) of those DLLs after MyDll.dll
to ensure that they are extracted before MyDll.dll
is loaded, and you likely need the loadwithalteredsearchpath
option as well. Example from the help:
procedure ADllFunc(hWnd: Integer; lpText, lpCaption: String; uType: Cardinal);
// A.dll depends on B.dll
external 'ADllFunc@files:A.dll,B.dll stdcall loadwithalteredsearchpath';
Upvotes: 7