本文的参考来源于:http://www.cnblogs.com/skynet/archive/2010/07/10/1774964.html
具体的代码可以参考这篇文章:https://m.oschina.net/blog/172670
C++是一个面向对象语言(虽不是纯粹的面向对象语言),它支持函数的重载,重载这个特性给我们带来了很大的便利。为了支持函数重载的这
个特性,C++编译器实际上将下面这些重载函数:
1
2
3
4
|
void
print(
int
i);
void
print(
char
c);
void
print(
float
f);
void
print(
char
* s);
|
编译为:
1
2
3
4
|
_print_int
_print_char
_print_float
_pirnt_string
|
但是在C语言中,并没有重载的特性,所以,不会像c++那样编译出一个叫做_print_int的函数,而是直接编译出_print函数,这样,在
C语言中并没有重载和类这些特性,故并不像C++那样print(int i),会被编译为_print_int,而是直接编译为_print等。因此如果直接在C++中调用C的函数会失败,因为连接是调用C中的print(3)时,它会去找_print_int(3)。因此extern "C"的作用就体现出来了。
//t.cpp
#include "lib.h"
#include "stdio.h"
/*extern "C"{*/
#include "lib.h"
/*}*/
int main (int argc, char** argv)
{
say_hello() ;
return 0;
}
//lib.c
int say_hello ()
{
printf("hello world, ");
return 0;
}
//lib.h
#ifndef __LIB_H__
#define __LIB_H__
int say_hello ();
#endif
比较重要的extern “C”是在编译的过程中就会做一些活动,在编译阶段就会将函数名编译成为自己想要的,链接的时候再去找对应的函数,所以,如果是如上的几个文件采用的编译链接方式是g++ lib.c t.cpp 那么是可以正常的编译链接的,因为都是用的g++ = =。
简单的编译模式是:
但是如果我们用的编译选项是gcc -c lib.c 然后g++ t.cpp 然后是 g++ lib.o t.o 那么就会出现找不到函数定义的问题。
如果编译成为动态链接库,编译方式是:
gcc lib.c -fPIC -shared -o libtest.so
g++ t.cpp -L. -ltest -o test
因为把extern “C” 注释掉了,所以undefined reference to `say_hello,虫合虫合