代码之家  ›  专栏  ›  技术社区  ›  DK.

如何用MSVC定义C++中的外部结构、C结构返回函数?

  •  2
  • DK.  · 技术社区  · 16 年前

    以下源文件将不使用MSVC编译器(v15.00.30729.01)编译:

    /* stest.c */
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    struct Test;
    
    /* NB: This may be extern when imported by another module. */
    struct Test make_Test(int x);
    
    struct Test { int x; };
    
    struct Test make_Test(int x)
    {
        struct Test r;
        r.x = x;
        return r;
    }
    
    #ifdef __cplusplus
    }
    #endif
    

    编译 cl /c /Tpstest.c

    stest.c(8) : error C2526: 'make_Test' : C linkage function cannot return C++ class 'Test'
            stest.c(6) : see declaration of 'Test'
    

    编译时没有 /Tp cl 把文件当作C++处理是很好的。该文件还编译C和C++模式下的DigalMARMARS C和GCC(来自明文)。我也用过 -ansi -pedantic -Wall 与海湾合作委员会,它没有投诉。

    由于我将进入下面的原因,我们需要编译这个文件作为C++的MSVC(而不是其他),但是函数被编译为C。实际上,我们需要一个普通的C编译器。。。除了六条线。是否有一个开关或属性或我可以添加的东西,这将允许工作?


    有问题的代码(尽管不是上述代码;这只是一个简化的例子)是由代码生成器生成的。

    作为其中的一部分,我们 需要 能够生成浮点NANS和无穷大作为常量(长故事),意味着我们必须用C++中的MSVC编译,以便真正做到这一点。我们只找到了一个可行的解决方案 只有 在C++模式下工作。

    我们正在把代码包装起来 extern "C" {...} 因为我们想控制损坏和调用约定,这样我们就可以与现有的C代码进行接口。。。也因为我相信C++编译器,我可以扔一个小百货公司。我也试过包装 只是 reinterpret_cast 线路输入 extern "C++" {...} ,但这当然行不通。可怜。

    我发现了一个潜在的解决方案,它需要对声明进行重新排序,以便得到完整的结构定义 之前 函数在12月前完成,但是由于codegen的执行方式,这非常不方便,所以我想 真正地 如果可以的话我想避免走那条路。

    3 回复  |  直到 14 年前
        1
  •  2
  •   Michael Burr    16 年前

    这是一个有趣的问题。正如您所说,将代码编译为C代码不会产生错误。只有MSVC在编译成C++代码时,似乎遇到了麻烦。

    由于其他C++编译器对代码没有问题,这在MSVC可能是一个错误,但我可以看到MSVC如何可能有这个错误的理由。当C++编译器命中:

    struct Test;
    

    这是一个不完整的声明 struct Test 结构试验 将包含C++特定项(虚拟函数、继承等)。请注意,在 extern "C" 块仍然可以使用所有C++设施;这个 语言链接规范仅适用于“由声明引入的所有函数声明符、函数名和变量名的函数类型”(7.5/4“链接规范”)。

    所以我可以看到当MSVC的C++编译器遇到一个 函数返回一个不完整的类型,它可能会决定在该点返回一个错误,以防该类型不是普通的C样式POD类型。

    C++标准确实说(7.5/9)链接规范“”:

    因此,如果MSVC有理由不允许,它可能会有一些回旋余地(标准方面) 外部“C”

    这些都帮不了你-这只是我的猜测。

    编译为C(或重新排列声明)。但我可以想象,这可能是一个噩梦,开始工作,尤其是保持。

        2
  •  3
  •   Hans Passant    16 年前

    必须在标头中声明结构。执行此操作时,错误将消失:

    #ifdef __cplusplus
    extern "C" {
    #endif
    
    struct Test { int x; };
    struct Test make_Test(int x);
    
    struct Test make_Test(int x)
    {
        struct Test r;
        r.x = x;
        return r;
    }
    
    #ifdef __cplusplus
    }
    #endif
    
        3
  •  0
  •   MK.    16 年前

    你为什么让外人进来

    extern struct Test make_Test(int x)
    {
        struct Test r;
        r.x = x;
        return r;
    }
    

    它不是外部的,你正在定义它。