在 C 代码中使用 C++ 库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/199418/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 13:39:04  来源:igfitidea点击:

Using C++ library in C code

c++cgccglibc

提问by Misha M

I have a C++ library that provides various classes for managing data. I have the source code for the library.

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

I want to extend the C++ API to support C function calls so that the library can be used with C code and C++ code at the same time.

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

I'm using GNU tool chain (gcc, glibc, etc), so language and architecture support are not an issue.

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

Are there any reasons why this is technicallynot possible?

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

Are there any gotcha'sthat I need to watch out for?

是否有任何疑难杂症的,我需要注意?

Are there resources, example code and/or documentation available regarding this?

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



Some other things that I have found out:

我发现的其他一些事情:

  1. Use the following to wrap your C++ headers that need to be used by C code.
  1. 使用以下内容来包装 C 代码需要使用的 C++ 头文件。

#ifdef __cplusplus
extern "C" {  
#endif  
//  
// Code goes here ...  
//  
#ifdef __cplusplus  
} // extern "C"  
#endif
  1. Keep "real" C++ interfaces in separate header files that are not included by C. Think PIMPL principlehere. Using #ifndef __cplusplus #errorstuff helps here to detect any craziness.
  2. Careful of C++ identifiers as names in C code
  3. Enums varying in size between C and C++ compilers. Probably not an issue if you're using GNU tool chain, but still, be careful.
  4. For structs follow the following form so that C does not get confused.

    typedef struct X { ... } X
    
  5. Then use pointers for passing around C++ objects, they just have to be declared in C as struct X where X is the C++ object.

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

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

All of this is courtesy of a friend who's a wizard at C++.

所有这些都是由一位 C++ 向导的朋友提供的。

采纳答案by Greg Hewgill

Yes, this is certainly possible. You will need to write an interface layer in C++ that declares functions with extern "C":

是的,这当然是可能的。您将需要用 C++ 编写一个接口层来声明函数extern "C"

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

Then, you will call foo()from your C module, which will pass the call on to the realFoo()function which is implemented in C++.

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

If you need to expose a full C++ class with data members and methods, then you may need to do more work than this simple function example.

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

回答by Alex B

C++ FAQ Lite: "How to mix C and C++ code".

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

Some gotchas are described in answers to these questions:

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

  • [32.8] How can I pass an object of a C++ class to/from a C function?
  • [32.9] Can my C function directly access data in an object of a C++ class?
  • [32.8] 如何将 C++ 类的对象传入/传出 C 函数?
  • [32.9] 我的 C 函数可以直接访问 C++ 类对象中的数据吗?

回答by ejgottl

Main gotcha: exceptions can not be caught in C. If there is the possibility of an exception rising in the C++ code, either write your C code or your C++ wrappers very carefully. Conversely, exception like mechanisms (i.e., longjump) in the C code (as found in various scripting languages) are not required to invoke destructors for C++ objects on the stack.

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

回答by David Nehme

you can mix C/C++ code. If your main() function in in C++, then you just need to make sure your c functions are declared

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

extern "C"

If your main is C, then you are probably OK except for static variables. Any constructors with your static variables are supposed to be called before main() start. This won't happen if C is your main. I you have a lot of static variables, the best thing to do is to replace static variables with singletons.

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