extern“C“的作用以及c/c++代码互调-创新互联

一、目的

相信从事嵌入开发的小伙伴肯定遇到过使用第三库的情景,有时候可能是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元起,快前往官网查看详情吧


标题名称:extern“C“的作用以及c/c++代码互调-创新互联
网站URL:http://myzitong.com/article/cscpgd.html