C++库以C的形式导出详解
这个问题是如何出现的?
虽然c++语言是兼容c语言的,或者说是在c语言基础上‘升级来的’,但是,两者肯定是不同的编译机制。c++语言由于有重载、命名空间等特性,编译器编译时需要对已有的函数名、变量名进行修饰,这个过程称为“名称修饰”、“名称装饰”。
例如:
int add(int a); double add(double a);
编译器修饰后,可能为_zaddi,_zaddd。
如何使用
C++库可以以C的形式导出。这通常是为了使C++库能够被C程序或其他不支持C++ ABI的编程语言调用。为了实现这一点,可以使用`extern "C"`来禁用C++的名称修饰(name mangling),从而使函数能够以C的方式导出。
下面是一个简单的示例,展示如何在C++中导出一个函数,使其可以被C程序调用:
C++ 代码(库实现)
cpp
// mylibrary.cpp #include <iostream> extern "C" { void my_function() { std::cout << "Hello from C++!" << std::endl; } }
cpp
// mylibrary.h #ifndef MYLIBRARY_H #define MYLIBRARY_H extern "C" { void my_function(); } #endif // MYLIBRARY_H
`
C 代码(调用库)
c // main.c #include <stdio.h> // 包含C++库的头文件 #include "mylibrary.h" int main() { // 调用C++库中的函数 my_function(); return 0; }
编译和链接
1. 编译C++库:
bash g++ -c mylibrary.cpp -o mylibrary.o ar rcs libmylibrary.a mylibrary.o
2. 编译并链接C程序:
bash
gcc main.c -L. -lmylibrary -o main
在这个示例中,`extern "C"` 告诉编译器使用C语言的名称修饰规则,这样生成的符号可以被C程序正确识别和调用。
请注意,如果你的库中有多个函数或类,并且你希望它们都以C的形式导出,你可以将`extern "C"`放在一个头文件的外层:
cpp
// mylibrary.h #ifndef MYLIBRARY_H #define MYLIBRARY_H #ifdef __cplusplus extern "C" { #endif void my_function(); // 其他函数声明 #ifdef __cplusplus } #endif #endif // MYLIBRARY_H
这样可以确保头文件中的所有声明都使用C语言的名称修饰规则。