【问题标题】:which gcc distro supports __declspec(dllexport) _cdecl and _stdcall哪个 gcc 发行版支持 __declspec(dllexport) _cdecl 和 _stdcall
【发布时间】:2016-02-04 17:05:43
【问题描述】:

在 C++Builder 工作了很长时间后,我正在尝试开始使用 mingw (MinGW-w64) 和 eclipse。我很困惑。

我的工作主要围绕供应商提供的以 MSVC 为中心的 API。它由 3 个头文件和几个库组成。我可以在 C++Builder 中使用它们的头文件,但在使用 g++ 时遇到了很多问题。

#define GX_WRAPPER_FUNC  __declspec(dllexport)
#define GX_STANDARD_FUNC
#define GX_WRAPPER_CALL  _cdecl
#define GX_STANDARD_CALL _stdcall


#define GX_OBJECT_PTR    void*

#define GX_VAR
#define GX_CONST         const

#define GX_VOID          void
#define GX_LONG          long
#define GX_DOUBLE        double
#define GX_HANDLE        long

#define GX_LONG_PTR      long*
#define GX_DOUBLE_PTR    double*
#define GX_HANDLE_PTR    long*
#define GX_ASTR_PTR      char*
#define GX_WSTR_PTR      wchar_t*
#if defined(GEO_UTF8)
   #define GX_STR_PTR       GX_ASTR_PTR
#elif defined( _UNICODE)
   #define GX_STR_PTR       GX_WSTR_PTR
#else
   #define GX_STR_PTR       GX_ASTR_PTR
#endif

#endif


#ifdef __cplusplus
   extern "C" {
#endif



/*---------------- Copy_3DN[_public] ----------------*/

GX_WRAPPER_FUNC GX_LONG GX_WRAPPER_CALL
Copy_3DN(GX_VAR   GX_OBJECT_PTR,
         GX_CONST GX_HANDLE_PTR,
         GX_CONST GX_HANDLE_PTR);
GX_STANDARD_FUNC GX_LONG GX_STANDARD_CALL
Std_Copy_3DN(GX_VAR   GX_OBJECT_PTR,
             GX_CONST GX_HANDLE_PTR,
             GX_CONST GX_HANDLE_PTR);
...hundreds more like this

这会产生一大堆“预期的初始化程序之前”错误。

通过像这样重新定义前 4 个定义,我取得了一些成功:

#ifdef __GNUC__
    #define GX_WRAPPER_FUNC  __attribute__ ((dllexport))
    #define GX_STANDARD_FUNC
    #define GX_WRAPPER_CALL
    #define GX_STANDARD_CALL

#else
    #define GX_WRAPPER_FUNC  __declspec(dllexport)
    #define GX_STANDARD_FUNC
    #define GX_WRAPPER_CALL  _cdecl
    #define GX_STANDARD_CALL _stdcall
#endif

但是后来遇到就吐了

GX_WRAPPER_FUNC GX_LONG GX_WRAPPER_CALL
RegisterResourceTracking_GEO(GX_VAR   GX_OBJECT_PTR,
                             GX_CONST GX_LONG_PTR,
                             GX_OBJECT_PTR,
                             void (_stdcall *param3)(void*));

我真的很想在不编辑它们的情况下使用这些标题,并且我看到一些参考表明正确选择 gcc 发行版可能支持这种语法,但我已经尝试了一个数字,但没有运气。我已经尝试过 MinGW-w64 和 Nuwen 和 TDM 的 i686 和 x86-64 变体。我不关心跨平台问题,因为主机应用程序只是 Windows,出于我自己的顽固原因,我不想放弃并切换到 MSVC。

那么,有没有支持这种语法的 gcc 发行版?如果不是,阻力最小的路径是什么?

干杯

【问题讨论】:

  • 你试过#define __stdcall __attribute__((stdcall))吗?
  • 单下划线版输了,用两个。所以 __stdcall 而不是 _stdcall。
  • @BenVoigt 有效。您可以将其发布为答案以便我接受吗?

标签: c++ windows gcc


【解决方案1】:

作为一种解决方法,您可以扩展宏定义集以涵盖 gcc 无法识别的关键字:

#ifdef __GNUC__
    #define _cdecl __attribute__((cdecl))
    #define __cdecl __attribute__((cdecl))
    #define _stdcall __attribute__((stdcall))
    #define __stdcall __attribute__((stdcall))

    #define GX_WRAPPER_FUNC  __attribute__ ((dllexport))
#else
    #define GX_WRAPPER_FUNC  __declspec(dllexport)
#endif

作为奖励,这些使这里的原始定义有效:

#define GX_STANDARD_FUNC
#define GX_WRAPPER_CALL  _cdecl
#define GX_STANDARD_CALL _stdcall

(FWIW,请注意,这是可能的,因为大多数 MSVC 扩展都是新的简单关键字,从保留的标识符空间到实现。gcc 的多令牌 __attribute__(()) 魔术使反向映射完全不可能。所以任何时候您使用 gcc 不可移植的功能编写代码,将它们隐藏在宏后面。)

【讨论】:

    猜你喜欢
    • 2018-08-05
    • 2023-01-26
    • 1970-01-01
    • 2015-02-24
    • 2017-06-11
    • 2011-06-14
    • 2018-04-27
    • 2016-03-25
    • 2011-11-23
    相关资源
    最近更新 更多