将DLL导入Inno-Setup的问题

时间:2010-08-23 17:15:58

标签: c++ dll dllimport inno-setup

我在innosetup安装脚本中导入C ++ DLL。 DLL代码如下:

void __stdcall SetFbParam(char *dbFileName,char *dbTableName,char *dbParamName,char *dbParamValue){
//of no use here and doesn't change anything}

在Innosetup中,我使用

导入它
procedure FBset(dbFileName,dbTableName,dbParamName,dbParamValue: String;);

external 'SetFbParam@files:MyDll.dll stdcall setuponly';

但是,在启动安装程序期间,我总是遇到运行时错误,说它无法导入我的dll。我尝试了各种调用约定,但总是失败。 如果它有任何重要性,我正在运行带有UAC的Win7 x64(安装程序请求权限提升并在此之后崩溃)。

确切的信息是:
错误
运行时错误(在-1:0):
无法导入
DLL:C:\ Users \ Nevod \ AppData \ Local \ Temp \ is-6LOEC.tmp \ MyDll.dll

dll在那里。

谢谢!

3 个答案:

答案 0 :(得分:6)

MyDll.dll是32位吗?

MyDll.dll是否依赖于同一目录中的任何其他DLL?如果是这样,您需要在“MyDll.dll”之后列出这些DLL的名称,以确保在加载MyDll.dll之前将它们解压缩,并且您可能需要“loadwithalteredsearchpath”选项同样。 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

答案 1 :(得分:3)

(我知道它已经老了,但也许还有其他一些点击这个)

很可能该函数的名称在C ++ DLL中被破坏了。我有同样的问题,我能够通过重新编译DLL来解决它。简而言之:

如果从C ++导出类似于:

的内容
void __stdcall foo() 

您将获得一个名为(Visual Studio)的函数:

?foo@@YGXXZ

要防止名称损坏,您应该使用export“C”指令。示例(Visual Studio)

extern "C" __declspec( dllexport ) void __stdcall foo()

但是我发现Visual Studio会继续破坏,你会得到类似的东西:

_foo@0

这里解释了我能够得到干净名字的唯一方法: C++ DLL Export: Decorated/Mangled names

罪魁祸首确实是__stdcall。如果从声明中删除它:

extern "C" __declspec( dllexport ) void foo()

即使没有DEF文件,您也会再次获得干净的导出。 IMO这应该足够好了,因为上面的代码声明了一个“C”导出函数,而C的默认调用约定是stdcall。但是我没有时间和处理来验证这一点,因为添加DEF文件比导航asm代码和检查堆栈指针更容易:)

答案 2 :(得分:1)

为了在InnoSetup的[Code]部分中使用DLL,请确保:

  • DLL处于32位模式(即使安装程序是为64位构建并且以64位模式运行)
  • 导出的函数有 extern "C" __declspec( dllexport ) 改性剂
  • 使用cdecl调用约定,因为stdcall mangles name(http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx)。当然可以在InnoSetup import语句中指定受损名称。但是使用cdecl似乎更容易