【问题标题】:Linking Openssl library(calling convention _cdecl) with a dll(calling convention _stdcall)将 Openssl 库(调用约定 _cdecl)与 dll 链接(调用约定 _stdcall)
【发布时间】:2018-12-25 05:20:09
【问题描述】:

我将 openssl 库 (openssl.lib) 包含到一个 dll 中。当我构建这个 dll 时,我发现很少有链接器错误。我调试并发现链接器错误是由于dll的调用约定造成的。我的 dll 使用 _stdcall 调用约定,而 openssl 使用 _cdecl 调用约定。我无法更改我的 dll 的调用约定,因为它是现有解决方案的一部分。所以我尝试将openssl的调用约定改为_stdcall。但我做不到,结果出现了以下构建错误。

\crypto\ui\ui_openssl.c(591) : 错误 C2440: 'function' : 无法从 'void (__stdcall *)(int)' 转换为 'void (__cdecl *)(int)' .\crypto\ui\ui_openssl.c(591):警告 C4024:“信号”:不同 形参和实参的类型 2 .\crypto\ui\ui_openssl.c(591) : 错误 C2440: '=' : 无法从 'void (__cdecl *)(int)' 转换为 'void (__stdcall *)(int)' .\crypto\ui\ui_openssl.c(592):错误 C2440: 'function' : 无法从 'void (__stdcall *)(int)' 转换为 'void (__cdecl *)(int)'

导致构建错误的代码行是:

static void pushsig(void)
{ 
#ifndef OPENSSL_SYS_WIN32
   int i;
#endif
#ifdef SIGACTION
 struct sigaction sa;

 memset(&sa,0,sizeof sa);
 sa.sa_handler=recsig;
#endif

#ifdef OPENSSL_SYS_WIN32
 savsig[SIGABRT]=signal(SIGABRT,recsig); // **line 591**
 savsig[SIGFPE]=signal(SIGFPE,recsig);   // **line 592**
 savsig[SIGILL]=signal(SIGILL,recsig);

如何使用 _stdcall(/Gz) 调用约定构建 openssl 库?或者有其他解决方案吗?

注意:signal是一个windows API(调用约定是_cdecl)。请参考此链接https://msdn.microsoft.com/en-us/library/xdkz3x12.aspx

谢谢, 萨蒂什。

【问题讨论】:

  • 混合使用不同调用约定的代码没有问题,在您尝试更改调用约定之前最初的链接器错误是什么?
  • 以下是在将 openssl.lib(_cdecl 调用约定)链接到 dll(_stdcall 调用约定)时观察到的链接器错误。错误 LNK2001:无法解析的外部符号 _HMAC_CTX_cleanup@4 错误 LNK2001:无法解析的外部符号 _HMAC_Final@12 错误 LNK2001:无法解析的外部符号 _HMAC_Update@12 错误 LNK2001:无法解析的外部符号 _HMAC_Init_ex@20

标签: c++ windows dll openssl calling-convention


【解决方案1】:

从命令行更改默认调用约定是一件很不寻常的事情。我认为你有两个选择:

  1. 浏览openssl头文件并将所有函数显式标记为__cdecl
  2. 删除调用约定命令行选项,并用__stdcall显式标记项目中需要stdcall的函数

当您在项目中引入其他第三方库时,选项 2 将大大减少您的麻烦。在标头中显式标记函数对于您的 dll 的使用者来说也将更加可靠,而不是依赖于未设置为通常值 __cdecl 的默认调用约定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-19
    • 2010-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-17
    相关资源
    最近更新 更多