基本作用:
一:extern有两个作用
作用一:当其与"C"一起连用时,如extern “C” void m_simtest(int runtime_t)(注意这个函数可以使在实际项目开发中动态库中的函数,这个函数的实现基于C约定的风格)。为什么要这么用:因为C++相较于C支持函数重载,不同的编译器在编译源代码的时候会出现不同的解释。而C不支持函数重载,所以extern “C” ,也就限制了C++代码编译的时候的重载,使得编译器在编译m_simtest函数时遵从C规则。
作用二:就是声明函数或全局变量的作用范围的关键字,具体用法可以参考我上篇博客。静态变量与全局变量。
二:博客主要内容:
本篇博客主要将extern的第一个用法,也就是作用一extern C。
1.在C++中引用C语言的函数如下代码:
//cExample.h
#ifndef C_EXAMPLE_H
#define C_EXAMPLE_H
int add(int x,int y);
#endi
声明C接口的头文件
//cExample.c文件
#include "cExample.h"
int add( int x, int y )
{
return x + y;
}
这个文件用来生成动态库windows下dll,linux下so
//cppFile.cpp
#include <iostream>
extern "C"
{
#include "cExample.h"
}
using namespace std;
int main(int argc, char* argv[])
{
cout <<add(2,3)<<endl;
return 0;
}
用来验证在cpp中调用动态库中的C接口的测试cpp文件。
这里如果cppFile.cpp中不加extern C在linux中将会出现如下编译报错
usr/bin/ld: /tmp/ccFaycx3.o: in function main': cppFile.cpp:(.text+0x1e): undefined reference to
add(int, int)’
collect2: error: ld returned 1 exit status
make: *** [Makefile:18:test] 错误 1。
原因分析:C++中调用C风格实现的接口,包含的头文件或者是调用的接口需要用extern "C"修饰。
ubuntu中编译makefile
src = $(wildcard ./src/*.c )
srcpp = $(wildcard ./src/*.cpp)
obj = $(patsubst ./src/%.c,./compile/%.o,$(src))
inc_path = ./inc
lib_path = ./lib
compile_file = ./compile
myArgs = -Wall -g
ALL:test
#test:$(lib_path)/libcExample.so $(srcpp)
#gcc $^ -o $@ $(myArgs) -l cExample -L ./lib
test:lib/libcExample.so \
src/cppFile.cpp
g++ -o test ./src/cppFile.cpp -l cExample -L ./lib -I $(inc_path)
#libcExample.so: $(obj)
#gcc -shared -o $(lib_path)/libcExample.so $^ $(myArgs)
lib/libcExample.so:compile/cExample.o
gcc -shared -o lib/libcExample.so compile/cExample.o
#$(obj):./compile/%.o:./src/%.c
#gcc -c $< -o $@ $(myArgs) -I $(inc_path) -fPIC
compile/cExample.o:src/cExample.c
gcc -o compile/cExample.o -c src/cExample.c -I $(inc_path) -fPIC
clean:
rm -rf lib/* compile/* test
.PHONY: clean ALL
了解内容:
C中调用C++接口
可参考博客C++中extern C含義深層探索