十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
相信从事嵌入开发的小伙伴肯定遇到过使用第三库的情景,有时候可能是C++中调用C库,有时候可能又是C中调用C++库;如果你遇到过,那你肯定知道extern "C"的作用.
目前创新互联建站已为数千家的企业提供了网站建设、域名、网络空间、成都网站托管、企业网站设计、玉泉网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。本篇的目的就是给大家介绍C/C++互相调用的原理和实践。
二、介绍首先我们需要明确以下几点:
c++支持重载,c++中函数编译后在符号表中的名字跟函数名本身有些区别
c不支持重载,c中函数编译后在符号表中的名字没有任何改动
假设我们有这样一个头文件print_hello.h
#ifndef PRINT_HELLO_H
#define PRINT_HELLO_H
#ifdef __cplusplus
extern "C" {
#endif
void print_hello(const char *info);
#ifdef __cplusplus
}
#endif
#endif
其中下面代码片段的作用为了避免头文件重复包含导致编译错误
#ifndef PRINT_HELLO_H
#define PRINT_HELLO_H
#endif
下面的代码片段中我们将print_hello函数根据当前使用的编译器决定是否包含在extern "C"声明中。如果是gcc编译,那么__cplusplus宏是未定义的;如果是c++编译那么print_hello函数就必须要按照C语言规范来编译。
#ifdef __cplusplus
extern "C" {
#endif
void print_hello(const char *info);
#ifdef __cplusplus
}
#endif
extern/static关键字用于声明变量或者函数的可见性,extern声明的变量或者函数代表除了本模块外其他模块也可见;static声明的变量或者函数只有本模块可见。
我们可以通过extern声明变量或者函数多次,但是只能定义一次。
__cplusplus只有是c++编译器时才会定义。
关键字"C"是指按照C的language linkage进行编译链接。
三、实战print_hello.c源代码
#include "print_hello.h"
#includevoid print_hello(const char *info) {
printf("hello %s\n", info);
}
print_hello.h源代码
#ifndef PRINT_HELLO_H
#define PRINT_HELLO_H
void print_hello(const char *info);
#endif
gcc编译后查看函数符号
gcc -c print_hello.c -o print_hello.o
readelf -a print_hello.o
从上图我们可以看到gcc编译后的print_hello函数符号名还是print_hello。
下面我们再用g++编译一下看下输出结果
g++ -c print_hello.c -o print_hello.o
readelf -a print_hello.o
从上图我们可以看到g++编译后的print_hello函数符号名变成了_Z11print_helloPKc
下面我们来看一下通过extern "C" 声明编译后的函数名称
print_hello.h源代码
#ifndef PRINT_HELLO_H
#define PRINT_HELLO_H
#ifdef __cplusplus
extern "C" {
#endif
void print_hello(const char *info);
#ifdef __cplusplus
}
#endif
#endif
g++编译查看符号信息
g++ -c print_hello.c -o print_hello.o
readelf -a print_hello.o
再次看一下函数符号信息
从上图我们可以确认通过extern "C" 限定后print_hello函数符号跟用gcc编译后的效果一样。
那我们再来确认一下通过g++编译后的print_hello函数能不能被c调用
main.c源代码
#include "print_hello.h"
int main() {
print_hello("world");
return 0;
}
gcc编译后查看符号表
gcc main.c print_hello.o -o main
readelf -a main
注意print_hello.o是通过g++编译后的目标文件
从上图可以确认c的main程序中的确链接上print_hello函数。
以上,就是extern "C"在c/c++互相调用的作用
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧