在C代码中使用c++库。

时间:2021-02-20 18:24:00

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 technically not possible?

为什么这在技术上是不可能的?

Are there any gotcha's that 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.
  2. 使用下面的方法来包装需要由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 principle here. Using #ifndef __cplusplus #error stuff helps here to detect any craziness.
  2. 在单独的头文件中保持“真正的”c++接口,而不是C。使用#ifndef __cplusplus #错误信息有助于检测任何疯狂。
  3. Careful of C++ identifiers as names in C code
  4. 在C代码中小心使用c++标识符。
  5. Enums varying in size between C and C++ compilers. Probably not an issue if you're using GNU tool chain, but still, be careful.
  6. 在C和c++编译器之间不同大小的枚举。如果您使用的是GNU工具链,这可能不是问题,但是要小心。
  7. For structs follow the following form so that C does not get confused.

    对于结构,遵循下面的形式,这样C就不会被混淆。

    typedef struct X { ... } X
    
  8. 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.

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

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

所有这些都是由一个在c++的向导的朋友提供的。

4 个解决方案

#1


63  

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

是的,这当然是可能的。您需要在c++中编写一个接口层,它声明了外部“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++.

然后,您将从您的C模块调用foo(),它将通过调用在c++中实现的realFoo()函数。

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++类,那么您可能需要做更多的工作,而不是这个简单的函数示例。

#2


18  

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.8]如何将c++类的对象传递给/从C函数?
  • [32.9] Can my C function directly access data in an object of a C++ class?
  • [32.9]我的C函数能直接访问c++类对象中的数据吗?

#3


11  

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.

Main gotcha:异常不能在C中捕获。如果c++代码中出现异常的可能性,可以非常小心地编写C代码或c++包装器。相反,异常的机制(例如在C代码中(在各种脚本语言中发现),不需要对堆栈中的c++对象调用析构函数。

#4


3  

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是你的主,这就不会发生。我有很多静态变量,最好的方法是用单例替换静态变量。

#1


63  

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

是的,这当然是可能的。您需要在c++中编写一个接口层,它声明了外部“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++.

然后,您将从您的C模块调用foo(),它将通过调用在c++中实现的realFoo()函数。

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++类,那么您可能需要做更多的工作,而不是这个简单的函数示例。

#2


18  

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.8]如何将c++类的对象传递给/从C函数?
  • [32.9] Can my C function directly access data in an object of a C++ class?
  • [32.9]我的C函数能直接访问c++类对象中的数据吗?

#3


11  

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.

Main gotcha:异常不能在C中捕获。如果c++代码中出现异常的可能性,可以非常小心地编写C代码或c++包装器。相反,异常的机制(例如在C代码中(在各种脚本语言中发现),不需要对堆栈中的c++对象调用析构函数。

#4


3  

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是你的主,这就不会发生。我有很多静态变量,最好的方法是用单例替换静态变量。