http://blog.csdn.net/imcainiao11/article/details/7369447

前言:以前见到extern "C"这样的语句,只是简单地知道跟外部链接有关,但是没有深刻理解它的意思。

首先,为什么要使用extern "C"修饰符?

C++调用其它语言的函数,由于编译器生成函数的机制不一样,所以需要经过特殊处理,才可以调用。调用C语言的函数,需要在函数声明的地方语句extern "C"。如果不使用该语句,在链接的时候,编译器就会报以下这种错误。

Test.obj : error LNK2019: 无法解析的外部符号 "void __cdecl DeleteStack(struct _Node *)" (?DeleteStack@@YAXPAU_Node@@@Z),该符号在函数 _main 中被引用。

然后是如何使用?

应该怎么使用该语句呢?

刚开始,我简单地在C++源文件的前面使用该语句声明,但是还是出错,而且是在编译阶段就报错。

  1. error C2732: 链接规范与“DeleteStack”的早期规范冲突。

为什么会出现这个错误呢?因为C++源文件已经引入了C的头文件,在头文件里,声明该函数时没有extern修饰,而这里有extern修饰,所以冲突了。解决的办法有两个。

一。在C头文件中加上extern修饰符。

直接加,也不行。因为C源文件也包含了这个头文件,当编译C源文件时,就会出现错误。所以,需要一种机制来区分是编译C还是C++文件。方法如下:

  1. #ifdef __cplusplus
  2. extern "C"
  3. #endif
  4. void DeleteStack(Stack stack);

因为在编译C++文件时,自动定义预处理器名字__cplusplus,而编译C时,没有该处理器名字。所以只有编译C++时,才有符号extern “C”。

此外,链接指示extern "C"有单个和复合两种形式。以上为单个形式,复合形式可以同时将几个函数声明为extern "C"

  1. extern "C" {
  2. void DeleteStack(Stack stack);
  3. void PrintStack(Stack stack);
  4. void Pop(Stack stack);
  5. }

加上预处理器名字如下:

  1. #ifdef __cplusplus
  2. extern "C" {
  3. #endif
  4. void DeleteStack(Stack stack);
  5. void PrintStack(Stack stack);
  6. void Pop(Stack stack);
  7. #ifdef __cplusplus
  8. }
  9. #endif

二。编写一个C++风格的头文件,在这里添加extern修饰符。

使用方法一,很简单。但是如果该头文件是别人写好,你无法修改。这个时候就要使用其它方法了。方法是定义C++自己的头文件,文件名为"CStack.h"

    1. // CStack.h
    2. extern "C" {
    3. #include "Stack.h";
    4. }

C++调用C函数的更多相关文章

  1. ng-repeat循环出来的部分调用同一个函数并且实现每个模块之间不能相互干扰

    使用场景:用ng-repeat几个部分,每个部分调用同一个函数,但是每个模块之间的功能不能相互干扰 问题:在用repeat实现.content块repeat的时候打算这样做:新建一个空的数组(nmbe ...

  2. 深入理解javascript系列(4):立即调用的函数表达式

    本文来自汤姆大叔 前言 大家学JavaScript的时候,经常遇到自执行匿名函数的代码,今天我们主要就来想想说一下自执行. 在详细了解这个之前,我们来谈了解一下“自执行”这个叫法,本文对这个功能的叫法 ...

  3. EC笔记,第二部分:9.不在构造、析构函数中调用虚函数

    9.不在构造.析构函数中调用虚函数 1.在构造函数和析构函数中调用虚函数会产生什么结果呢? #; } 上述程序会产生什么样的输出呢? 你一定会以为会输出: cls2 make cls2 delete ...

  4. EC笔记,第二部分:5.了解C++默默编写并调用哪些函数

    5.了解C++默默编写并调用哪些函数 1.C++空类 C++会为一个空类建立以下函数 (1).默认构造函数 (2).默认拷贝构造函数 (3).析构函数 (4).赋值运算符(如果成员包含引用类型或con ...

  5. C++构造函数中不能调用虚函数

    在构造函数中调用虚函数,并不会产生多态的效果,就跟普通函数一样. c++ primer 第四版中497页15.4.5构造函数和析构中的虚函数讲到,如果在构造函数或析构函数中调用虚函数,则运行的是为构造 ...

  6. ZeroMQ接口函数之 :zmq_errno – 返回errno的值给调用此函数的线程

    ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_errno zmq_errno(3)         ØMQ Manual - ØMQ/3.2.5 Name zm ...

  7. cocos2dx 3.x(获得父类的node型指针调用父类函数this->getParent())

    void CenterLayer::zhanzheng(CCObject* pSender){ ((GameScene*)this->getParent())->showLayer(Gam ...

  8. 09——绝不在构造和析构函数中调用virtual函数

    在base class构造期间,virtual函数不是virtual函数. 构造函数.析构函数中不要调用virtual函数.

  9. LR常用函数以及调用自定义函数

    2.LR常用函数以及调用自定义函数 2.1.LR常用函数以及对信息的判断 2.1.1. LR内部自定义函数 在LR脚本中定义变量和编写自定义函数,需将变量的声明放在脚本其他内容的上方,否则会提示[il ...

  10. lua如何调用C++函数

    第一步是定义函数.所有在Lua中被调用的C/C++函数将使用下面一类指针进行调用: typedef int (*lua_CFunction) (lua_State *L); 换句话说,函数必须要以Lu ...

随机推荐

  1. QML引擎的演进,第一部分

    原文链接:Lars Knoll – Evolution of the QML engine, part 1 QML作为一项技术对于Qt的成功变得越来越重要.它允许创建流畅的动画界面,与现今的市场预期相 ...

  2. QPainter类的一些问题

    QPainter painter1(this);//新建类 painter1.setRenderHint(QPainter::Antialiasing,true);//设置反锯齿 painter1.s ...

  3. PRML

    PRML 学习之 第一章 介绍 Introduction #欢迎共同学习和讨论,由于本文将不断修改,谢绝转载 模式识别问题具有重要且久远的历史.比如,16世纪开普勒发现行星运动定律,又如20世纪出发现 ...

  4. python之路-Day10

    操作系统发展史介绍 进程.与线程区别 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 ...

  5. ssh config host

    Host mygithub HostName github.com User git IdentityFile ~/.ssh/github/id_rsa IdentitiesOnly yes

  6. Oracle中的sql操作符 和分析函数

    Oracle中的操作符算术操作符:无论是在sqlserver,或者是java中,每种语言它都有算术操作符,大同小异. Oracle中算术操作符(+)(-)(*)(/) 值得注意的是:/ 在oracle ...

  7. MySQL查询今天/本周/上周/本月/上个月份的数据

    MySQL查询的方式很多,下面为您介绍的MySQL查询实现的是查询本周.上周.本月.上个月份的数据,如果您对MySQL查询方面感兴趣的话,不妨一看. 查询当前今天的数据 SELECT name,sub ...

  8. javascript for循环练习

    有一对幼兔,幼兔1个月后长成小兔,小兔1个月后长成成兔并生下一对幼兔,问几年后有多少对兔子,幼兔.小兔.成兔对数分别是多少. 幼兔 1 小兔 0 成兔 0幼兔 0 小兔 1 成兔 0 幼兔 1 小兔 ...

  9. 枚举全排列(包括数列中有重复数)的C语言实现

    据说是用了DFS的思想--然鹅并不知道这是DFS. 主要就是选取一个数放到数组相应位置上,然后递归的排列剩下的数组,将剩下的数组递归排列完了之后再把数放回去,然后这一层递归就返回了-- 有重复数的话遇 ...

  10. hdu 3579 Hello Kiki (中国剩余定理)

    Hello Kiki Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...