链接指示:extern "C"

  C++程序有时需要调用其他语言编写的函数,最常见的是调用C语言编写的函数。像所有其他名字一样,其他语言中的函数名字也必须在C++中进行声明,并且该声明必须指定返回类型和形参列表。对于其他语言编写的函数来说,编译器检查其调用方式与处理普通C++函数的方式相同,但生成的代码有所区别。C++使用链接指示(linkage directive)指出任意非C++函数所用的语言。

  声明一个非C++函数:

  链接指示可以有两种形式:单个或复合。链接指示不能出现在类定义或函数定义的内部。

  例如:

  单语句:  extern "C" size_t strlen(const char *);

  复合语句:extern "C" {

      int strcmp(const char*, const char*);

      char *strcat(char*, const char*);

  }

  链接指示与头文件:
  复合语句

  extern "C" {

    #include <string.h>

  }

  指向extern "C"函数的指针:

  编写函数所用的语言是函数类型的一部分。(指向其他语言编写的函数的指针必须与函数本身使用相同的链接指示)

  extern "C" void (*pf)(int);

  当我们使用pf调用函数时,编译器认定当前调用的是一个C函数。

  指向C函数的指针与指向C++函数的指针是不一样的类型。

  链接指示对整个声明都有效:

  当我们使用链接指示时,他不仅对函数有效,而且对作为返回类型或形参类型的函数指针也有效。

  //f1是一个C函数,它的形参是一个指向C函数的指针

  extern "C" void f1( void(*)(int) );

  因为链接指示同时作用于声明语句中的所有函数,所以如果我们希望给C++函数传入一个指向C函数的指针,则必须使用类型别名。

  //FC是一个指向C函数的指针

  extern "C" typedef void FC( int );

  //f2是一个C++函数,该函数的形参是指向C函数的指针

  void f2(FC *);

  导出C++函数到其他语言:

  通过使用链接指示对函数进行定义,我们可以令一个C++函数在其他语言编写的程序中可用。

  //calc函数可以被C程序调用

  extern "C" double calc( double dparm ) {/*......*/}

  编译器将为该函数生成适合指定语言的代码

  对链接到C的预处理器的支持

  有时需要在C和C++中编译同一个源文件,为了实现这一目的,在编译C++版本的程序时预处理器定义 __cplusplus(两个下划线)。利用这个变量,我们可以在编译C++程序的时候有条件地包含进来一些代码:

  #ifndef __cplusplus

  //正确:我们在编译C++程序

  extern "C"

  #endif

  int strcmp( const char*, const char* );

  重载函数与链接指示:

  C语言不支持函数重载,因此也不难理解为什么一个C链接指示只能用于说明一组重载函数中的某一行了:

  //错误:两个extern "C"函数的名字相同

  extern "C" void print ( const char* );

  extern "C" void print ( int );

  如果在一组重载函数中有一个C函数,则其余函数必定都是C++函数。

时间: 2024-12-08 23:38:58

链接指示:extern "C"的相关文章

C、C++编译,链接,extern链接

1 //b.cpp 2 3 #inlcude <iostream> 4 5 void b() 6 { 7 std::cout<<"fun b"; 8 } 9 10 //a.cpp 11 extern void b(); 12 13 int main() 14 { 15 b(); 16 return 0; 17 } 18 19 //makefile 20 testA: a.o b.o 21 g++ -o testA a.o b.o 22 23 clean: 24

C++ Primer 学习笔记_108(大结局!!!)_特殊工具与技术 --固有的不可移植的特征[下]

特殊工具与技术[大结局] --固有的不可移植的特征[下] 三.链接指示:extern "C" C++ 程序有时需要调用用其他程序设计语言编写的函数,最常见的一语言是C 语言.像任何名字一样,必须声明用其他语言编写的函数的名字,该声明必须指定返回类型和形参表.编译器按处理普通 C++ 函数一样的方式检查对外部语言函数的调用,但是,编译器一般必须产生不同的代码来调用用其他语言编写的函数.C++ 使用链接指示指出任意非 C++ 函数所用的语言. 1.声明非C++函数 链接指示不能出现在类定义

C++ Primer 笔记——固有的不可移植的特性

1.为了支持底层编程,C++定义了一些固有的不可移植的特性,所谓不可移植特性是指因机器而异的特性. 2.一个位域中含有一定数量的二进制位,位域在内存中的布局是机器相关的.位域的类型必须是整型或枚举类型,因为带符号位位域的行为是由具体实现确定的,所以在通常情况下我们使用无符号类型保存一个位域. typedef unsigned int Bit; class test { Bit A : 2; // A占2位 Bit B : 1; // B占1位 Bit C : 3; // C占3位 }; 如果可能

C++中的RTTI(转)

转自:http://blog.csdn.net/mannhello/article/details/5217954 RTTI 是“Runtime Type Information”的缩写,意思是:运行时类型信息.它提供了运行时确定对象类型的方法.本文将简略介绍 RTTI 的一些背景知识.描述 RTTI 的概念,并通过具体例子和代码介绍什么时候使用以及如何使用 RTTI:本文还将详细描述两个重要的 RTTI 运算符的使用方法,它们是 typeid 和 dynamic_cast. 其实,RTTI 在

extern &quot;C&quot;——用“C”来规约在C++中用C的方式进行编译和链接

C++中的extern “C”用法详解     extern "C"表明了一种编译规约,其中extern是关键字属性,“C”表征了编译器链接规范.对于extern "C"可以理解成在C++/C中的混合编程的编译指令.用“C”来规约在C++中用C的方式进行编译和链接. extern "C" 包含双重含义,从字面上即可得到:首先,被它修饰的目标是“extern”的:其次,被它修饰的目标是“C”的.让我们来详细解读这两重含义. 1.    被exter

关于存储持续性,作用域,链接性,static与extern

存储持续性:变量从声明到销毁. 自动存储持续性:自动变量(如在函数内int a;)的持续性为自动,在代码块({...}或函数内)中被创建,执行完函数或代码块后销毁,内存被释放.如在函数内(包括main)声明自动变量,则函数结束后就销毁. 静态存储持续性:在函数外(如在main之前声明int a;另外函数内不能嵌套定义,即main中是不能再定义一个函数的)或使用static定义的变量,他们的存储持续性在程序(main)运行的整个过程中都存在,但作用域会有区别.在函数外声明的变量,他的作用域(下面讲

链接属性

链接属性(linkage) ---- external (外部).internal(内部).none(无) 链接属性处理不同文件中的标识符 external:属于该链接属性的标识符无论声明多少次.位于几个源文件,都表示同一个实体 internal:属于该链接属性的标识符在同一个源文件的所有声明表示同一实体,不同源文件中的声明表示不同实体 none:多个声明均表示不同实体 typedef char *a; int b; int c (int d){ int e; int f (int g); }

extern关键字总结

extern 变量/函数 这种情况下的extern说明变量或者函数声明在其他的源文件里,而不用include头文件的方式来引用该函数,在链接时,链接器在各个模块中搜索这个变量或者函数来进行最终链接. extern 变量 在一个源文件里定义了一个数组:char a[6]; 在另外一个文件里用下列语句进行了声明:extern char *a: 请问,这样可以吗?  答案与分析: 不可以,程序运行时会告诉你非法访问.原因在于,指向类型T的指针并不等价于类型T的数组.extern char *a声明的是

C++生成二级制文件过程(预处理-&gt;编译-&gt;链接 )

转载请注明出处 Windows下C++编程,通过VC生成工程,编写C++源文件,点运行,代码没问题直接出结果.VC什么都帮我们搞了,不了解其中过程也完全没问题. 转到linux下写c++,总觉得有点虚,毕竟很多时候需要自己去构建.网上找了一些相关的文章,大多讲得高深,弄懂其过程后来写一篇不高深但易懂的,方便回忆.有不准确的地方欢迎指正. C++包括源文件(.cpp)和头文件(.h),头文件包含变量的声明和类定义,源文件包含变量的定义.当然你也可以只用源文件来组织程序,但使用.h文件可以使程序结构