extern “C”总结

学了就忘,忘了再学。有时感觉自己几乎就是一个跳梁小丑。没有办法,只好多记些笔记。


本文版权归作者和博客园共有

FROM: http://www.cnblogs.com/graphics/archive/2010/12/24/1916343.html


经常看到如下代码:

#ifdef _cplusplus

extern "C" {

#endif

#include "XXX.h"

#ifdef _cplusplus

}

#endif

解释:

extern "C"的作用是,告诉C++编译器,下面的代码按照C的方式进行编译,说白了,不要对这些函数进行名字重整(function name mangling)。通常在C++程序中使用C函数或者模块时,需要用到这个功能。

原因:

C++为了支持函数重载,将编译后的函数名做了重整(mangled name),比如下面的函数

int add(int a, int b) ;

在C中编译完的名字就是add,而在C++中,编译完就变成了add_int_int(举例而已,实际因编译器而异),这样在函数名字后面加上参数的类型,就可以区分不同的重载函数了,比如还有另一个函数

float add(float a, float b) ;

在C++中,它会被编译成add_float_float,这就是C++区分重载函数的机制

可是问题也随之而来

C++进行名字重整,而C不进行重整。当C++程序引用C的函数时,它会按照重整后的名字去目标文件(.obj)中去寻找对应的函数,而目标文件中存放的却是C版本的函数,名字对不上,所以根本找不到!

怎么办呢?

这就是extern “C” 存在的一个原因:

它告诉C++,包含在extern “C”{ //…}块中的东西是C版本的,你编译的时候不要进行名字重整,否则你链接的时候就无法找到我!


于是上面的代码也就不难理解了,光说不练是扯淡,上代码

我们简单的定义一个C头文件和实现文件,只包含一个add函数

CClass.h 内容如下

#ifndef __CClass_H__

#define __CClass_H__

extern int add(int a, int b) ;

#endif // end __CClass_H__

CClass.c 内容如下

#include "CClass.h"

int add(int a, int b)

{

return a + b ;

}

下面我们用一个C++程序来引用这个C文件

main.cpp 内容如下

#define _cplusplus // 为了测试,强加一句

#ifdef _cplusplus

extern "C" {

#endif

#include "CClass.h"

#ifdef _cplusplus

}

#endif

#include <iostream>

using namespace std ;

int main(void)

{

int result = add(1, 2) ;

cout << result << endl ;

system("pause") ;

return 0 ;

}

如果没有#include <iostream>之前那些代码而只是仅仅包含

#include "CClass.h"一句

你就会得到下面的错误

error LNK2019:unresolved external symbol "int __cdecl add(int,int)" (?add@@YAHHH@Z) referenced in function _main

显然这是一个链接错误,因为找不到对应的函数定义

当然你也可以简写成下面的形式,直接在extern “C”块中包含你想调用的函数

extern "C"

{

int add(int a, int b) ;

};

#include <iostream>

using namespace std ;

int main(void)

{

int result = add(1, 2) ;

cout << result << endl ;

system("pause") ;

return 0 ;

}

这在C++程序中是没有问题的,但是如果是在C程序中,则会出现编译错误,因为C中不允许extern “C”出现

另一个需要extern “C”的场合是当C程序调用C++的东西时

按照如下步骤做即可

1. 在C++的.h文件中用extern “C”{}声明将被C程序使用的函数

2. 在C++的.cpp文件中实现上面的函数

3. 在.c文件中用extern声明要使用的C++函数

4. 使用即可

注意:切不可在.c文件中包含C++的.h文件,那样编译无法通过

上代码:

CPPClass.h中声明add函数

#ifndef __CPPClass_H__

#define __CPPClass_H__

extern "C"

{

int add(int a, int b) ;

};

#endif // end __CPPClass_H__

CPPClass.cpp实现add函数

#include "CPPClass.h"

int add(int a, int b)

{

return a + b ;

}

main.c 内容如下

#include <stdio.h>

//#include "CPPClass.h" // 不要包含头文件,否则编译不过

extern int add(int a, int b) ; // 只需显示声明要调用的函数即可

int main(void)

{

int result = add(1, 2) ; //使用函数

printf("%d", result) ;

return 0 ;

}


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/264069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

人脸颜值评分软件_在线算个颜值,特科学的那种 | 知多少

用 AI&#xff0c;科学的为颜值打个分。用 AI&#xff0c;打造科学颜值打分器https://www.zhihu.com/video/1185672892095848448图文版本送给不方便打开的朋友 (●u●)」如何科学的为颜值打个分&#xff1f;三庭五眼、四高三低&#xff1f;脸部是否对称&#xff1f;是否与本民族…

图片翻转

图片翻转 原文:图片翻转本人录制技术视频地址&#xff1a;https://edu.csdn.net/lecturer/1899 欢迎观看。这一节继续为大家介绍CSS3的动画效果: 图片翻转。 在iOS中的章节中&#xff0c;我也介绍过类似的效果&#xff0c;如果感兴趣的话&#xff0c;请点击这里查看&#xff1a…

【原】页面跳转以及表单提交中有中文的解决办法

这两天一直碰到一个郁闷的问题&#xff0c;在对表单进行提交的时候&#xff0c;用户名是中文的&#xff0c;怎么测试都不通过, 今天上午突然想起来是不是因为中文字符编码的问题!经过测试&#xff0c;果然是因为这个问题&#xff01; 现在把解决方法贴出来&#xff01;呵呵&…

架构设计学习网址

http://learninghard.blog.51cto.com/all/6146675转载于:https://www.cnblogs.com/haiy/p/4155727.html

实验吧之NSCTF misc250

下载的是一个流&#xff0c;用wireshark打开&#xff0c;由于原题是这样的&#xff1a;小绿在学习了wireshark后&#xff0c;在局域网内抓到了室友下载的小东东0.0 你能帮他找到吗&#xff1f;说明我们应该重点关注http传送的东西&#xff1a; 这里面一共有四个http文件&#x…

西澳大学商科专业排名_澳洲西澳大学优势专业排名多少

澳洲西澳大学优势专业排名多少西澳大学农业和林业专业在2018年QS世界排名中排名第32西澳大学解剖学和生理学专业在2018年QS世界排名中排名第13西澳大学地球与海洋科学专业在2018年QS世界排名中排名第32西澳大学土木结构工程专业在2018年QS世界排名中排名第37西澳大学矿产和采矿…

基于SOUI开发的应用展示

本页面列出基于SOUI开发的产品 欢迎使用SOUI的朋友提供资源&#xff1a;setoutsoft#qq.com #-> U大师 http://www.udashi.com EiisysIM: 是一款为工作场景而设计的企业即时通讯软件, &#xff0c;含PC版和手机版。具有完善的即时通讯、文件传输、语音通话等功能。通讯录由企…

供应商寄售库存管理_【论文解读】物流联合外包下库存管理模式对供应链运作的影响...

物流联合外包下库存管理模式对供应链运作的影响作者&#xff1a;冯颖&#xff0c;林晴&#xff0c;张景雄&#xff0c;张炎治目录 1 引言2 问题描述3 数学模型4 协调模型5 数值算例6 结论1 引言传统库存管理模式下&#xff0c;供应链中各节点企业的库存管理各自为政&#xff0c…

ViewState

因为现在的ASP.NET网站是基于http这种无状态协议的。大家应该都懂。 在ASP.NET的我们提交的一个页面&#xff0c;虽然看起来是一样的&#xff0c;但是他们本质上已经不是同一个页面了。而是我们现在看见的页 面获取了之前提交的那个页面的一些状态值。关于这点&#xff0c;到第…

查看自己Android设备分辨率

/*在Android中加入下面代码&#xff0c;用数据线连接上手机、运行下便知道自己Android设备的分辨率是多少了*/DisplayMetrics mDisplayMetrics new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(mDisplayMetrics);Log.i("Resolution",mDis…

python之布尔值——待补充……

61数据类型 633 3括号&#xff1a;{} [] () 3基本类型: int str bool 1:None 转载于:https://www.cnblogs.com/wjlv/p/10818455.html

SQLserver2000 实例管理工具

1、企业管理器是microsoft管理控制台(Microsoft management console)的一个插件。插件是运行在MMC中的部件、他不能独立运行&#xff0c;但必须包含着MMC中。企业管理器提供MMC形式的界面。像IIS、MTS也是MMC插件 2、查询分析器右边有模板选项卡&#xff0c;可以创建现成的模板…

linux设置nexus开机自启动_CentOS7配置nexus开机自启动

CentOS7配置nexus开机自启动新建nexus启动脚本进入/etc/init.d目录&#xff0c;新建脚本文件nexus// 进入/etc/init.d[rootlinux_maven etc]# cd /etc/init.d/// 新建脚本文件nexus[rootlinux_maven init.d]# vim nexus脚本内容:#!/bin/bash#chkconfig:2345 20 90#description:…

怎么看懂别人的代码

一&#xff0c;程序的结构及流程基本上是顺序&#xff0c;循环&#xff0c;选择。 二&#xff0c;业务数据---->对象形式(js-->{}, new function(){}/Java object) 业务流程---->传入参数&#xff0c;返回值。 流程可以先看作一步&#xff0c;然后再分为两步&#xff…

c语言6-2

#include<stdio.h> int main(){int a[3][3]{2,3,5,45,23,65,8,46,67};int s,t;sa[0][0]a[2][2]a[1][1];ta[0][2]a[1][1]a[2][0];printf("%d\n%d\n",s,t);return 0;} 转载于:https://www.cnblogs.com/p201821440019/p/10819405.html

怎么把ai从c盘移动到d盘_ai暂存盘怎么设置-AI设置暂存盘的教程 - 河东软件园

Adobe Illustrator简称AI&#xff0c;这款软件使用用户绘制图形的软件&#xff0c;它被大量的使用在了logo的设计中。相信每一位logo设计人员对它都不陌生吧&#xff1f;AI和PS都是同属于adobe旗下的图形设计软件&#xff0c;因此很多的设置功能都是一样的&#xff0c;例如暂存…

48个越吃越瘦的诀窍 - 生活至上,美容至尚!

1.吃好早餐。早餐是开启一天新陈代谢的钥匙。营养师推荐理想早餐&#xff1a;牛奶谷类&#xff08;面包、馒头、麦片等&#xff09;一份水果或蔬菜一个鸡蛋。2.每天25&#xff5e;30克的纤维。纤维不能被人体消耗吸收&#xff0c;但在体内停留时间长&#xff0c;能制造饱腹感&a…

c 最大子序列和_算法总结:左神class8—跳台阶+最长递增公共子序列

【跳台阶】有n级台阶&#xff0c;一个人每次上一级或者两级&#xff0c;问有多少种走完n级台阶的方法?public int s1(int n){ if (n< 1){ return 0; if(n 1 || n 2){ return n; return s1(n - 1) s1(n - 2);}【最长递增子序列长度】给定数组arr&#xff0c;返回arr…

[转载]dynamic的小坑--RuntimeBinderException:“object”未包含“xxx”的定义

创建一个控制台项目和一个类库项目, 在类库中创建一个匿名对象&#xff0c;然后在控制台中访问它&#xff0c;代码如下&#xff1a; 控制台: namespace ConsoleApplication1 {class Program{static void Main(string[] args){dynamic dyc ClassLibrary1.TestClass.Test();Cons…

mysql 触发器 定时触发_mysql 触发器和存储过程组合使用,实现定时触发操作

mysql可以实现定时触发功能&#xff0c;比如说定于某某时间mysql数据库做什么工作&#xff0c;或每隔多长时间做什么工作。第二种情况应用还是比较广的&#xff0c;比如说我希望每天检查一下我的数据信息&#xff0c;超过一个月的无用信息清除以腾出空间供其他存储数据使用&…