【问题标题】:GCC: header only C-wrapper around a C++ template function (no linker requirements)GCC:围绕 C++ 模板函数的仅标头 C 包装器(无链接器要求)
【发布时间】:2019-02-19 20:52:16
【问题描述】:

我的问题是我想在 C 中调用一些模板函数。

因此,我声明了一个extern "C" 函数作为包装函数,它调用这个模板函数。

我知道,我需要用 c++ 编译器编译包装函数,然后我得到一个目标文件,我可以链接到一个普通的 c 程序。

问题是,我已经编写了一个只有头文件的 C++ 库,我想在 C 中使用它,但是在 CI 中,一旦我需要将 C 程序与包装器链接起来,就不能再制作库头文件了功能。

那么是否存在任何生成仅标题的 c 库的方法,它调用 c++ 模板函数?这种方法应该可以在 GCC 中工作,绝对没有问题,如果它是非标准的,需要几个 pragma、cli 参数或其他东西。

我认为,一个可能的解决方案是在文件上以 C 模式调用 gcc,在特定行上,可以在头文件中从 C 切换到 C++。此 C++ 开关执行实际的模板调用,然后执行切换回 C 编译器。有什么方法吗?

例如像这样:

#include <iostream>

#define SWITCH_TO_CPP_COMPILER() /*TODO: is this possible?*/
#define SWITCH_BACK_TO_C_COMPILER() /*TODO: is this possible?*/

#ifdef __cplusplus
extern "C" {
#endif
    inline bool wrapper();
#ifdef __cplusplus
}
#endif


SWITCH_TO_CPP_COMPILER();

template<bool tmp>
constexpr bool template_func() noexcept {
    return tmp;
}

inline bool wrapper() {
    return template_func<true>();
}

SWITCH_BACK_TO_C_COMPILER()

#include <stdio.h>

int main() {
    printf("%d\n", wrapper());
}

我已经看了几个问题,但他们没有回答:

C Wrapper for C++: How to deal with C++ templates?

how to write c wrapper around c++ code to expose class methods

Create a C wrapper around a C++ library that can be linked by a C linker

C wrapper around C++ library without unnecessary header files

【问题讨论】:

    标签: c++ c gcc


    【解决方案1】:

    C 包装器的全部意义在于让C++ 编译器为实例化的模板和包装器生成一个对象模块,并且让 C 编译器非常高兴地知道除了包装器之外的任何东西,已知/ 彻底调用了 extern 函数声明。

    这个东西不能只包含头文件:头文件被粗暴地包含在使用它的文件中,并且该文件将由 C 编译器处理,然后必须能够解析/实例化 C++ 模板除了包装函数,这显然是不可能的。解析 C++ 已经很复杂了,需要在半空中切换到不同的语言是完全疯狂的。

    如果您想将您的库用于“C 正确”程序,您必须有一个由 C++ 编译器编译的额外 TU。否则,无论您怎么想,都需要一些能够编译模板的 C++ 编译器,只需用 C++ 编译所有内容,如果您愿意,只需将 C 子集用于其余文件。

    您已经依赖于 C++ 编译器,并且很可能来自 C++ 标准库,因此除了总体方案中的编译速度之外,这不会有太大变化。

    【讨论】:

      【解决方案2】:

      记住 Matteo 在他的answer 中写的:

      确信 OP 想要的东西是不可能的,我试图找到一个实质性的论据。

      我比较了CC++ 的“翻译阶段”。

      关于预处理的第一阶段看起来非常相似,但从第 7 阶段(编译)开始,它变得非常不同。

      我几乎不怀疑任何编译器都可以从 C 切换到 C++ 并返回到翻译单元的中间(如果它符合标准的话)。

      【讨论】:

        猜你喜欢
        • 2013-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-15
        • 2022-07-13
        • 2015-04-13
        • 2016-04-20
        相关资源
        最近更新 更多