Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将DLL导入Inno安装程序时出现问题_C++_Dll_Dllimport_Inno Setup - Fatal编程技术网

C++ 将DLL导入Inno安装程序时出现问题

C++ 将DLL导入Inno安装程序时出现问题,c++,dll,dllimport,inno-setup,C++,Dll,Dllimport,Inno Setup,我在一个iNoStUpUnt脚本中导入一个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,dbParamN

我在一个iNoStUpUnt脚本中导入一个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在那里

谢谢

MyDll.dll是32位的吗

MyDll.dll是否依赖于同一目录中的任何其他dll?如果是这样,您需要在“MyDll.dll”之后列出这些dll的名称,以确保在加载MyDll.dll之前提取它们,并且您可能还需要“loadwithalteredsearchpath”选项。示例来自:

MyDll.dll是32位的吗

MyDll.dll是否依赖于同一目录中的任何其他dll?如果是这样,您需要在“MyDll.dll”之后列出这些dll的名称,以确保在加载MyDll.dll之前提取它们,并且您可能还需要“loadwithalteredsearchpath”选项。示例来自:

(我知道这首歌很老,但也许这首也有其他的热门歌曲)

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

如果你从C++导出的东西类似:

void __stdcall foo() 
_foo@0
您将获得一个名为(Visual Studio)的函数:

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

但是,我发现Visual Studio将继续出现问题,您会得到如下结果:

void __stdcall foo() 
_foo@0
我获得干净姓名的唯一方法如下:

罪魁祸首确实是stdcall。如果您将其从声明中删除:

extern "C" __declspec( dllexport ) void foo()
即使没有DEF文件,您也将再次获得干净的导出。在我看来,这应该足够好了,因为上面的代码声明了一个“C”导出函数,C的默认调用约定是stdcall。但是,我还没有时间和部署来验证这一点,因为添加DEF文件比导航asm代码和检查堆栈指针要容易得多:)

(我知道它很旧,但可能还有其他一些方法也会使用它)

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

如果你从C++导出的东西类似:

void __stdcall foo() 
_foo@0
您将获得一个名为(Visual Studio)的函数:

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

但是,我发现Visual Studio将继续出现问题,您会得到如下结果:

void __stdcall foo() 
_foo@0
我获得干净姓名的唯一方法如下:

罪魁祸首确实是stdcall。如果您将其从声明中删除:

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

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

要在InnoSetup的[code]部分使用DLL,请确保:

  • DLL处于32位模式(即使安装程序是为64位构建的,并且在64位模式下运行)
  • 导出的函数具有
    extern“C”\u declspec(dllexport)
    修饰语
  • 使用cdecl调用约定,因为stdcall会损坏名称()。当然,可以在InnoSetup导入语句中指定损坏的名称。但仅仅使用cdecl似乎更容易

要使用InnoSetup[代码]部分中的DLL,请确保:

  • DLL处于32位模式(即使安装程序是为64位构建的,并且在64位模式下运行)
  • 导出的函数具有
    extern“C”\u declspec(dllexport)
    修饰语
  • 使用cdecl调用约定,因为stdcall会损坏名称()。当然,可以在InnoSetup导入语句中指定损坏的名称。但仅仅使用cdecl似乎更容易

不要让我们猜测运行时错误消息。确切的消息是:error runtime error(at-1:0):无法导入dll:C:\Users\Nevod\AppData\Local\Temp\is-6LOEC.tmp\MyDll.dll该dll就在那里。而且您要导入的函数实际上也已导出?不要让我们猜测运行时错误消息。确切的消息是:error runtime error(at-1:0):无法导入dll:C:\Users\Nevod\AppData\Local\Temp\is-6LOEC.tmp\MyDll.dll该dll在那里。您导入的函数实际上也被导出了?“使用cdecl调用约定,因为stdcall会损坏名称”,请您详细说明一下,好吗?我不确定为什么,我没有时间玩它,但由于某些原因,使用stdcall编译的DLL导出了如下名称:
_function@8
编译同一DLL时,只需将项目的整体调用约定更改为cdecl,即可将导出的名称更改为
函数
。我已经用VS2010做了测试,你遇到了所谓的名称混乱,但我想这并不是建议你做什么的理由。我相信你可以。你提供的链接解释了如何在客户端使用它,而不是如何阻止它。我进一步研究了一下,发现这是u stdcall的正常行为:当然可以在InnoSetup import语句中指定损坏的名称。但是使用cdecl似乎更容易。你是对的,我认为它更容易(不过,如果你提到为什么你会这么建议的话还是可以的)。“使用cdecl调用约定,因为stdcall会损坏名称”,请你详细说明一下,好吗?我不知道为什么,我也没有时间玩它,但出于某些原因,我用它编译了一个DLL