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++函數庫。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章