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语言的名称修饰规则。

posted @ 2024-09-30 17:13  卖雨伞的小男孩  阅读(37)  评论(0编辑  收藏  举报