1

I am importing an C++ DLL in an innosetup 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 Innosetup, 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!

nnevod
  • 41
  • 2
  • 6

3 Answers3

6

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);
external 'ADllFunc@files:A.dll,B.dll stdcall loadwithalteredsearchpath'; //A.dll depends on B.dll
3

(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 export "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 :)

Community
  • 1
  • 1
Yalos
  • 31
  • 1
1

In order to use DLLs in InnoSetup's [Code] section please make sure:

  • DLL is in 32 bit mode (even if the installer is built for 64bit and is running in 64bit mode)
  • exported functions have extern "C" __declspec( dllexport ) modifier
  • use cdecl calling convention because stdcall mangles name (http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx). Of course it is possible to specify mangled name in InnoSetup import statement. But it seems easier to just use cdecl
rkudinov
  • 175
  • 12
  • *"Use cdecl calling convention because stdcall mangles name"*, could you elaborate this, please ? – TLama Mar 14 '15 at 11:39
  • I'm not sure why and I didn't have time to play with it, but for some reasons a DLL compiled with stdcall had exported name something like this: `_function@8` while compiling the same DLL just changing **overall calling convention of the project** to cdecl changed the exported name to `function`. I've made tests with VS2010 – rkudinov Mar 15 '15 at 12:35
  • You've met so called name mangling, but that's not a reason to suggest what you did, I guess. I believe you can [`stop VS to do that`](http://stackoverflow.com/q/1467144/960757). – TLama Mar 15 '15 at 12:46
  • The link you provided explains how to live with that in client, not how to stop this. I dig a bit more in it and found that this is a normal behavior for __stdcall: https://msdn.microsoft.com/en-us/library/zxk0tw93.aspx Of course it is possible to specify mangled name in InnoSetup import statement. But it seems easier to just use cdecl – rkudinov Mar 16 '15 at 13:33
  • You're right, I thought it's easier (still would be fine to mention why do you suggest this). – TLama Mar 17 '15 at 09:55