链接指示: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++函数。
链接指示:extern "C"的更多相关文章
- C/C++基础----特殊工具和技术 (重载new和delete,RTT,限定作用域的枚举类型,类成员指针,嵌套类,局部类,volatile,链接指示 extern “C”)
重载new和delete 1调用operator new( 或new[])标准库函数分配足够大的.原始的.未命名的内存空间以便存储特定类型的对象 2编译器运行相应地构造函数以构造这些对象,并为其传入初 ...
- 链接指示:extren"C"
C++程序有时需要调用其他语言编写的函数,最常见的是调用C语言编写的函数.像所有其他名字一样,其他语言中的函数名字也必须在C++中进行声明,并且该声明必须指定返回类型和形参列表.对于其他语言编写的函数 ...
- C和指针 第三章 链接属性 extern、internal、none
三种链接属性 组成一个程序有多个源文件,如果相同的标识符出现在多个源文件中,那么标识符的链接属性决定如何处理在不同文件中出现的标识符. 链接属性有三种: external:外部 多个源文件中的相同标识 ...
- C、C++编译,链接,extern链接
//b.cpp #inlcude <iostream> void b() { std::cout<<"fun b"; } //a.cpp extern vo ...
- C++调用C函数
http://blog.csdn.net/imcainiao11/article/details/7369447 前言:以前见到extern "C"这样的语句,只是简单地知道跟外部 ...
- RTTI(Runtime Type Information )
RTTI 是“Runtime Type Information”的缩写,意思是:运行时类型信息.它提供了运行时确定对象类型的方法.本文将简略介绍 RTTI 的一些背景知识.描述 RTTI 的概念,并通 ...
- C++ Primer 笔记——固有的不可移植的特性
1.为了支持底层编程,C++定义了一些固有的不可移植的特性,所谓不可移植特性是指因机器而异的特性. 2.一个位域中含有一定数量的二进制位,位域在内存中的布局是机器相关的.位域的类型必须是整型或枚举类型 ...
- C/C++ 复习
本文总结一下C++面试时常遇到的问题.C++面试中,主要涉及的考点有 关键字极其用法,常考的关键字有const, sizeof, typedef, inline, static, extern, ne ...
- extern "C"——用“C”来规约在C++中用C的方式进行编译和链接
C++中的extern “C”用法详解 extern "C"表明了一种编译规约,其中extern是关键字属性,“C”表征了编译器链接规范.对于extern "C& ...
随机推荐
- Python入门(六):标准库
操作系统接口 os模块提供了不少与操作系统相关联的函数. import os os.getcwd() # 返回当前的工作目录 os.chdir('d:/') # 修改当前的工作目录 os.system ...
- (转)QT中QWidget、QDialog及QMainWindow的区别
QWidget类是所有用户界面对象的基类. 窗口部件是用户界面的一个基本单元:它从窗口系统接收鼠标.键盘和其它事件,并且在屏幕上绘制自己.每一个窗口部件都是矩形的,并且它们按Z轴顺序排列.一个窗口部件 ...
- 3D游戏引擎〇 開始
游戏循环: 初始化:运行一些主要的初始化操作,如内存分配,资源获取.从磁盘载入数据等. 进入游戏循环:进入主游戏循环.用户不断地运行动作,知道退出主循环为止. 读取玩家输入:处理玩家输入,或将其存储到 ...
- mac同时安装多个jdk
DK8 GA之后,小伙伴们喜大普奔,纷纷跃跃欲试,想体验一下Java8的Lambda等新特性,可是目前Java企业级应用的主打版本还是JDK6, JDK7.因此,我需要在我的电脑上同时有JDK8,JD ...
- [LintCode] 合并排序数组II
class Solution { public: /** * @param A: sorted integer array A which has m elements, * but size of ...
- 简单工厂模式设计(java反射机制改进)
如果做开发的工作,工厂设计模式大概都已经深入人心了,比较常见的例子就是在代码中实现数据库操作类,考虑到后期可能会有数据库类型变换或者迁移,一般都会对一个数据库的操作类抽象出来一个接口,然后用工厂去获取 ...
- 几种常见数据库查询判断表和字段是否存在sql
1.MSSQL Server 表:select COUNT(*) from dbo.sysobjectsWHEREname= 'table_name': 字段:select COUNT(*) ...
- java中的printf
转载自: http://www.cnblogs.com/healthy-tree/archive/2012/08/07/2626665.html http://www.cnblogs.com/Tank ...
- 一篇搞定vue请求和跨域
vue本身不支持发送AJAX请求,需要使用vue-resource.axios等插件实现 axios是一个基本Promise的HTTP请求客户端,用来发送请求,也是vue2.0官方推荐的,同时不再对v ...
- ubuntu14 编译安装(升级)g++
编译安装(升级)g++ ubuntu14自带的g++为4.8.4,不支持c++11.现要将g++升至5.2.0 1.下载安装: 参考https://www.cppfans.org/1719.html ...