链接Openssl库(调用约定_cdecl)和dll(调用约定_stdcall)

时间:2018-07-17 13:21:59

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

我将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库?还是对此有其他解决方案?

注意:信号是Windows API(调用约定为_cdecl)。请参考此链接https://msdn.microsoft.com/en-us/library/xdkz3x12.aspx

谢谢, 沙沙语。

1 个答案:

答案 0 :(得分:0)

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

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

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