C语言extern的用法及作用

/*       procrank.h                             */

#include <stdio.h>

#ifndef PROCRANK_H

#define PROCRANK_H



#ifdef __cplusplus

extern "C" {

#endif



  extern void print_hello();



#ifdef __cplusplus

}

#endif



#endif



/*     procrank.c */

#include "procrank.h"
#include <stdio.h>

void print_hello()
{
	printf("hello world!\n");
	printf("hello world!\n");
}
	


/* main.cpp  */

#include "procrank.h"


int main()
{
	print_hello();
	return 0;
}
	

   (1)__cplusplus宏干什么的,  __cplusplus是cpp中的自定义宏,定义了该宏说明这是一段CPP的代码,所以这里的H文件的含义为:如果此文件用于CPP代码时,就加上exern "c".

  (2)C与C++函数汇编时的区别:

int f(void)
{
return 1;
} 


  在加入extern "C"的时候产生的汇编代码是:

.file "test.cxx"
.text
.align 2
.globl _f
.def _f; .scl 2; .type 32; .endef
_f:
pushl %ebp
movl %esp, %ebp
movl $1, %eax
popl %ebp
ret 


 但是不加入了extern "C"之后

.file "test.cxx"
.text
.align 2
.globl __Z1fv
.def __Z1fv; .scl 2; .type 32; .endef
__Z1fv:
pushl %ebp
movl %esp, %ebp
movl $1, %eax
popl %ebp
ret 


  两段汇编代码同样都是使用gcc -S命令产生的,所有的地方都是一样的,唯独是产生的函数名,一个是_f,一个是__Z1fv。

     从中,可以看出C与C++代码的不同了,也就是产生中间函数名时的命名机制已经发生了变化,相对来说,C比较简单,而C++则要更规范,更复杂一些。

    当我们使用C与C++混编时,或者说用C++代码复用C代码时,就会产生相应的问题,了支持原来的C代码和已经写好C库,需要在C++中尽可能的支持C,而extern "C"就是其中的一个策略。它的实际作用就是,在C++调用C函数库的时候,能够让C++代码正确地找到C函数库中的函数名,最终连接产生对应的C库文件中。

    从我们给出的例子,很容易就看出来了,C++调用C库时,是多了一个exern "c".

    这里需要注意的是,当我们的H头文件,如果只是纯粹的C文件头,这里是不支持使用extern "c"的.


    (3)从上面的第二条,可以看出,这里的extern 确实是为了确存C与C++混编而使用的一种策略,这也是C++的创始人为了兼容部分C代码而设计。

   

    (4)那C调用C++库呢?

     

/*       procrank.h                             */

#include <stdio.h>

#ifndef PROCRANK_H

#define PROCRANK_H

extern "C" void print_hello();

    

/*     procrank.cpp */

#include "procrank.h"
#include <stdio.h>

void print_hello()
{
	printf("hello world!\n");
	printf("hello world!\n");
}
	

/* main.c  */

//#include "procrank.h"

extern void print_hello();  //add

int main()
{
	print_hello();
	return 0;
}
	


   注意,这里使用了exern "c" void print_hello();这里是为了让C代码能够正确地调用C++函数库。




你可能感兴趣的:(C语言extern的用法及作用)