114

我有一个 C++ 库,它提供了各种用于管理数据的类。我有图书馆的源代码。

我想扩展 C++ API 以支持 C 函数调用,以便该库可以同时与 C 代码和 C++ 代码一起使用。

我正在使用 GNU 工具链(gcc、glibc 等),因此语言和架构支持不是问题。

有什么理由说明这在技术上是不可能的吗?

有什么我需要注意的问题吗

是否有与此相关的资源、示例代码和/或文档?


我发现的其他一些事情:

  1. 使用以下内容来包装 C 代码需要使用的 C++ 标头。

#ifdef __cplusplus
extern "C" {  
#endif  
//  
// Code goes here ...  
//  
#ifdef __cplusplus  
} // extern "C"  
#endif
  1. 将“真正的”C++ 接口保存在 C 不包含的单独头文件中。在这里考虑PIMPL 原则。在这里使用#ifndef __cplusplus #error东西有助于检测任何疯狂。
  2. 小心 C++ 标识符作为 C 代码中的名称
  3. C 和 C++ 编译器之间大小不同的枚举。如果您使用 GNU 工具链,这可能不是问题,但仍然要小心。
  4. 对于结构,请遵循以下形式,以免 C 混淆。

    typedef struct X { ... } X
    
  5. 然后使用指针来传递 C++ 对象,它们只需在 C 中声明为 struct X,其中 X 是 C++ 对象。

所有这一切都是由一位 C++ 天才朋友提供的。

4

4 回答 4

77

是的,这当然是可能的。您需要在 C++ 中编写一个接口层,该接口层使用以下命令声明函数extern "C"

extern "C" int foo(char *bar)
{
    return realFoo(std::string(bar));
}

然后,您将从foo()C 模块调用,该模块会将调用传递给realFoo()用 C++ 实现的函数。

如果您需要使用数据成员和方法公开一个完整的 C++ 类,那么您可能需要做的工作比这个简单的函数示例更多。

于 2008-10-13T23:33:49.063 回答
23

C++ FAQ Lite:“如何混合 C 和 C++ 代码”

这些问题的答案中描述了一些陷阱:

  • [32.8] 如何将 C++ 类的对象传递给/从 C 函数传递?
  • [32.9] 我的 C 函数可以直接访问 C++ 类的对象中的数据吗?
于 2008-10-13T23:46:19.710 回答
13

主要问题:不能在 C 中捕获异常。如果 C++ 代码中可能出现异常,请非常小心地编写 C 代码或 C++ 包装器。相反,C 代码(如在各种脚本语言中发现的)中的异常类机制(即,longjump)不需要为堆栈上的 C++ 对象调用析构函数。

于 2008-10-13T23:45:31.630 回答
3

您可以混合使用 C/C++ 代码。如果您的 main() 函数在 C++ 中,那么您只需要确保您的 c 函数已声明

extern "C"

如果你的 main 是 C,那么除了静态变量之外你可能没问题。任何带有静态变量的构造函数都应该在 main() 开始之前被调用。如果 C 是您的主要内容,则不会发生这种情况。我你有很多静态变量,最好的办法是用单例替换静态变量。

于 2008-10-13T23:40:34.060 回答