关于“#ifdef___cplusplus”_和__extern_C
更新时间:2023-08-25 04:48:01 阅读量: 教育文库 文档下载
关于extern "C" 和 extern “C” far的说明
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
宏定义里面这样写有什么作用啊?extern "C" 是啥意思啊! //这是条件编译,分别生成c代码or c++代码,
//如果定义了__cplusplus(c++的意思)就定义extern "C" ,这是兼容c函数的用法。
还有就是extern far void vectors();中 far 是什么意思啊?//far 是调用的方式,简单的说,比如代码较近,我们就可一用短指针访问,near 调用,但是如果表示代码的地址很长,就得用长指针或者间接访问,后者就是far 调用.
在CSL.H里面还会见到:
#ifdef __cplusplus
#define CSLAPI extern "C" far
#else
#define CSLAPI extern far
#endif
这里是不太明白 extern "C" far 和extern far 的区别。并且__cplusplus这个东西一般到底定义了没有?
不太明白这些东西。
在这里请教大家 多谢!
// 这个和你的编译器和工作环境有关系啊,如果你用c代码,__cplusplus就没用定义, //extern 是声明,表示这是个外部变量,定义在其他模块。
注意以下结构: #ifdef __cplusplus
extern "C"
{ #endif
#ifdef __cplusplus
}
#endif 宏定义里面这样写有什么作用啊?extern "C" 是啥意思啊? //这是条件编译,分别生成c代码or c++代码, //如果定义了__cplusplus(c++的意思)就定义extern "C" ,这是兼容c函数的用法。
还有就是extern far void vectors();中 far 是什么意思啊? //far 是调用的方式,简单的说,比如代码较近,我们就可以用短指针访问,near 调用,但是如果表示代码的地址很长,就得用长指针或者间接访问,后者就是far 调用。
在CSL.H里面还会见到:
#ifdef __cplusplus
#define CSLAPI extern "C" far
#else
#define CSLAPI extern far
#endif 这里是不太明白 extern "C" far 和extern far 的区别。并且__cplusplus这个东西一般到底定义了没有?
// 这个和你的编译器和工作环境有关系啊,如果你用c代码,__cplusplus就没用定义, //extern 是声明,表示这是个外部变量,定义在其他模块。
关于“#ifdef __cplusplus” 和 " extern "C" "
看一些程序的时候老是有
“#ifdef __cplusplus
extern "C" {
#endif”的定义,搞搞清楚是怎么回事:
Microsoft-Specific Predefined Macros
__cplusplus Defined for C++ programs only.
意思是说,如果是C++程序,就使用
extern "C"{
而这个东东,是指在下面的函数不使用的C++的名字修饰,而是用C的
The following code shows a header file which can be used by C and C++
client applications:
// MyCFuncs.h
#ifdef __cplusplus
extern "C" { //only need to export C interface if
// used by C++ source code
#endif
__declspec(dllimport ) void MyCFunc();
__declspec( dllimport ) void AnotherCFunc();
#ifdef __cplusplus
}
#endif
当我们想从C++中调用C的库时,(注,驱动是用C写的,连new、delete也不能用,郁闷)不能仅仅说明一个外部函数,因为调用C函数的编译代码和调用C++函数的编译代码是不同的。如果你仅说明一个外部函数, C++编译器假定它是
C++的函数编译成功了,但当你连接时会发现很可爱的错误。
解决的方法就是指定它为C函数:
extern "c" 函数描述
指定一群函数的话:
extern "C"{
n个函数描述
}
如果想C和C++混用的话:
#ifdef _cplusplus
extern "C"{
#endif
n个函数描述
#ifdef _cplusplus
}
#endif
extern "C"表示编译生成的内部符号名使用C约定。
C++支持函数重载,而C不支持,两者的编译规则也不一样。函数被C++编译后在符号库中的名字与C语言的不同。例如,假设某个函数的原型为: void foo( int x, int y ); 该函数被C编译器编译后在符号库中的名字可能为_foo,而C++编译器则会产生像_foo_int_int之类的名字(不同的编译器可能生成的名字不同,但是都采用了相同的机制,生成的新名字称为“mangled name”)。_foo_int_int这样的名字包含了函数名、函数参数数量及类型信息,C++就是靠这种机制来实现函数重载的。下面以例子说明,如何在C++中使用C的函数,
或者在C中使用C++的函数。
//C++引用C函数的例子
//test.c
#include <stdio.h>
void mytest()
{
printf("mytest in .c file ok\n");
}
//main.cpp
extern "C"
{
void mytest();
}
int main()
{
mytest();
return 0;
}
//在C中引用C++函数
在C中引用C++语言中的函数和变量时,C++的函数或变量要声明在extern "C"{}里,但是在C语言中不能使用extern "C",否则编译出错。
//test.cpp
#include <stdio.h>
extern "C"
{
void mytest()
{
printf("mytest in .cpp file ok\n");
}
}
//main.c
void mytest();
int main()
{
mytest();
return 0;
}
//综合使用
一般我们都将函数声明放在头文件,当我们的函数有可能被C或C++使用时,我们无法确定是否要将函数声明在extern "C"里,所以,我们应该添加
#ifdef __cplusplus
extern "C"
{
#endif
//函数声明
#ifdef __cplusplus
}
#endif
如果我们注意到,很多头文件都有这样的用法,比如string.h,等等。
//test.h
#ifdef __cplusplus
#include <iostream>
using namespace std;
extern "C"
{
#endif
void mytest();
#ifdef __cplusplus
}
#endif
这样,可以将mytest()的实现放在.c或者.cpp文件中,可以在.c或者.cpp文件中include "test.h"后使用头文件里面的函数,而不会出现编译错误。
//test.c
#include "test.h"
void mytest()
{
#ifdef __cplusplus
cout<< "coutmytest extern ok " <<endl;
#else
printf("printfmytest extern ok n");
#endif
}
//main.cpp
#include "test.h"
int main()
{
mytest();
return 0;
}
extern "C" 的用意
前些天,编程序是用到了很久以前写的C程序,想把里面的函数利用起来,连接发现出现了找不到具体函数的错误:
以下是假设旧的C程序库
C的头文件
/*-----------c.h--------------*/#ifndef _C_H_#define _C_H_externint
add(int x, int y);#endif
C的源文件
/*-----------c.c--------------*/int add(int x, int y){ return x+y;}
C++的调用
/*-----------cpp.cpp--------------*/#include "c.h"voidmain(){ add
(1, 0);}
这样编译会产生错误cpp.obj : error LNK2001: unresolved external symbol "int __cdecl add(int,int)"
(?add@@YAHHH@Z),原因是找不到add的目标模块这才令我想起C++重载的函数命名方式和C函数的命名方式,让我们回顾一下:C中函数编译后命名会在函数名前加以"_",比如add函数编译成obj文件时的实际命名为_add,而c++命名则不同,为了实现函数重载同样的函数名add因参数的不同会被编译成不同的名字
例如
int add(int , int)==>add@@YAHHH@Z,
float add(float , float )==>add@@YAMMM@Z,
以上是VC6的命名方式,不同的编译器会不同,总之不同的参数同样的函数名将编译成不同目标名,以便于函数重载是调用具体的函数。
编译cpp.cpp中编译器在cpp文件中发现add(1, 0);的调用而函数声明为extern int add(int x, int y);编译器就决定去找add@@YAHHH@Z,可惜他找不到,因为C的源文件把extern int add(int x, int y);编译成_add了;为了解决这个问题C++采用了extern "C",这就是我们的主题,想要利用以前的C程序库,那么你就要学会它,我们可以看以下标准头文件你会发现,很多头文件都有以下的结构
#ifndef __H#define __H#ifdef __cplusplusextern "C" {#endifexternintf1(int, int);extern int f2(int, int);extern int f3(int, int);
#ifdef __cplusplus}#endif#endif /*__H*/如果我们仿制该头文件可以得到
#ifndef _C_H_#define _C_H_#ifdef __cplusplusextern "C" {#endifextern
int add(int, int);#ifdef __cplusplus}#endif#endif /* _C_H_ */ 这样编译
/*-----------c.c--------------*/
intadd(int x, int y){
return x+y;
}
这时源文件为*.c,__cplusplus没有被定义,extern "C" {}这时没有生效对于C他看到只是extern int add(int, int);add函数编译成_add(int, int);
而编译c++源文件
/*-----------cpp.cpp--------------*/
#include "c.h"
void main()
{
add(1, 0);
}
这时源文件为*.cpp,__cplusplus被定义,对于C++他看到的是extern "C" {extern int add(int, int);}编译器就会知道 add(1, 0);调用的C风格的函数,就会知道去c.obj中找_add(int, int)而不是add@@YAHHH@Z;这也就为什么DLL中常看见extern "C" {},windows是采用C语言编制他首先要考虑到C可以正确调用这些DLL,而用户可能会使用C++而extern "C" {}就会发生作用
正在阅读:
关于“#ifdef___cplusplus”_和__extern_C08-25
2018年北京理工大学864法学综合1(刑法学、民法学)-标注提交版205-23
离散数学期末考试试题(有几套带答案)04-06
第十周周末作业09-13
矿用交流高密度电法仪介绍及对比情况04-14
统编版语文五年级下册第二单元语文同步测试题(含答案)05-01
大学生旅游消费行为特征分析及对策(终稿)12-26
建筑工程招投标工作概论 - 图文05-19
2011经济师考试中级房地产大纲08-09
法律基础题库及答案(四)11-26
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- cplusplus
- extern
- 关于
- ifdef
- 2013学年浙江省第一次五校联考
- 信托 - 信托知识讲座 - Trust
- 网络信息检索之Ei检索方法
- 住宅小区室外供电管网电气施工组织设计技术标
- GB50007-2002_建筑地基基础设计规范
- 证券投资学(吴晓求第三版)--第四&五章 宏观经济&行业分析
- 国家电网公司财务集约化管理实施方案2
- 移动支付陷怪圈
- 危货运输过程中危险、有害因素识别
- 2013管理类联考综合真题
- 企业人力资源管理战略规划
- 第五章 交通运输组织绩效评价指标
- Magento设计师手册(官方)中文翻译版(1)
- 【最新推荐】【精编试题】最新部编本人教版小学数学六年级(第一学期):教材过关卷(5)(考试必备试卷)
- 2016国家公务员面试必备100题(十二)
- 初一历史下册总复习及知识点,每章重点及综合题
- C语言程序设计实验与习题答案
- 高2014级《经济生活》框架与核心知识归纳
- 河海大学2005-2006学年第1学期《结构力学》期末考试试题与答案
- 通信机房电源及配套勘察设计要点