extern C的思考
背景
C语言和C++有着千丝万缕的联系,C++的另外一个名称是C With Class。同时差异也是有的。
C语言不支持重载函数,因为C语言编译器编译出来的函数在符号表中的标识符即为函数名本身(这里以VisualStudio2015
为例),支持重载函数意味着它们在符号表中的标识符是一样的,也就无法对他们进行区分。
C++支持重载函数,是因为C++编译器编译出来的函数在符号表中的标识符包含了参数的信息。我们知道重载函数本来就是靠参数的不同(参数个数与参数类型不同)来区分不同的函数,所以包括参数信息的标识符也就可以被分区开了。
担忧
如果C++中需要调用由C语言编译器编译出的动态库中的函数,该函数在C++中编译出的符号表中的标识带有参数信息,而其在动态库又不带参数信息,因此就会在链接时报错找不到该符号。
解决
我们可以使用extern "C"来声明使用的动态库中的函数:
extern "C" FunctionInDll();
...
// 调用FunctionInDll()
这样,C++编译器就会以C语言的方式来生成函数在符号表中的标识符,就和动态库中的标识符保持一致了。
案例
有如下VisualStudio2015
动态库工程TestDll
,其中包含两个文件:algorithm.h
、algorithm.cpp
。
algorithm.h
#pragma once__declspec(dllexport) int Add(int a, int b);
__declspec(dllexport) int Minus(int a, int b);
extern "C" __declspec(dllexport) int Multiply(int a, int b);
extern "C" __declspec(dllexport) int Devide(int a, int b);// 也可以使用如下的声明方式
//extern "C"
//{// __declspec(dllexport) int Multiply(int a, int b);
// __declspec(dllexport) int Devide(int a, int b);
//}
algorithm.cpp
#include "algorithm.h"int Add(int a, int b)
{return (a + b);
}int Minus(int a, int b)
{return (a - b);
}int Multiply(int a, int b)
{return a * b;
}int Devide(int a, int b)
{return a / b;
}
Multiply()
和Devide()
使用extern "C"
进行声明,编译工程,然后使用Dependency Walker.exe
打开生成的动态库TestDll.dll
:
可以看到使用和不使用extern "C"
进行声明生成的标识符的明显区别。
另外,可以测试下C语言中尝试编写重载函数的实际效果:在algorithm.h中
添加:
extern "C" __declspec(dllexport) int Devide(int a, int b, int c);
编译工程直接报错如下:不允许重载函数的第二个 C 链接。
1>------ 已启动全部重新生成: 项目: TestDll, 配置: Debug Win32 ------
1> algorithm.cpp
1>d:\vsproject\testdll\testdll\algorithm.h(7): error C2733: “Devide”: 不允许重载函数的第二个 C 链接
1> d:\vsproject\testdll\testdll\algorithm.h(6): note: 参见“Devide”的声明
========== 全部重新生成: 成功 0 个,失败 1 个,跳过 0 个 ==========
extern C的思考相关推荐
- 关于#define/extern/static的思考与总结
写在前面 全局常量作为开发人员一定是一个比较熟悉的概念.全局常量的写法自然也比较多,最近在进行项目的常量重构时看到了各种各样的写法,其中宏定义占大部分,然而有很多使用宏定义是不规范的,而且宏定义只是在 ...
- 《c语言修炼内功之第二种境界(看代码就是内存)之关键字系列二》
前言:这个系列内容我会深入讲解一下c语言中的重点内容,会把每一个知识点讲的更加底层些,会增强大家的c语言内功,从内存维度看代码你会有不同的理解. 这一节我主要讲一下多文件的知识,static修饰全局变 ...
- 嵌入在C++程序中的extern C
1.extern的作用 extern是C/C++语言中表明函数和全局变量作用范围(可见性)的关键字,可以告知编译器,用extern声明的函数和变量可以在本模块或其它模块中使用. 通常,在模块的头文件中 ...
- 何时在C ++中使用extern
本文翻译自:When to use extern in C++ I'm reading "Think in C++" and it just introduced the exte ...
- C++中extern “C”含义深层探索(zz)
1.引言 C++语言的创建初衷是"a better C",但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言,C++ ...
- Re: Programming C/C++中extern C含义深层探索
1.引言 C++语言的创建初衷是"a better C",但是这并不意味着C++中类似C 语言的全局变量和函数所采用的编译和连接方式与C 语言完全相同.作为一种欲与C 兼容的语言, ...
- 揭密 extern C
1.引言 C++语言的创建初衷是"a better C",但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言,C++ ...
- extern C的用法解析
extern "C"的用法解析 2012-03-20 23:29 by Rollen Holt, 20231 阅读, 6 评论, 收藏, 编辑 1.引言 C++语言的创建初衷是&q ...
- C/C++混合编程——extern C
1.引言 C++语言的创建初衷是"a better C",但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言,C++ ...
- C++中extern “C”含义深层探索
1.引言 C++语言的创建初衷是"a better C",但是这并不意味着C++中类似C语言的全局变量和函数所采用的编译和连接方式与C语言完全相同.作为一种欲与C兼容的语言,C++ ...
最新文章
- PHP5.5.13 + Apache2.4.7安装配置流程详解
- 2011-2012年《软件工程》本科期末试卷
- 编码调试:UnicodeDecodeError: ‘gbk‘ codec can‘t decode byte 0xaf in position 12: illegal multibyte sequen
- android开发全然退出activity
- k均值的损失函数_K-Means算法的实现
- python文件命名 数字,当文件存在时,文件名中的数字递增
- fcc jQuery 练习
- 路由协议的管理距离值
- Shell 编程学习笔记
- 2003下安装Comodo pro (通用)
- 宏基E5572g 键盘排线插拔 拆机局部
- 查看计算机启动项命令,运行命令开机启动项msconfig命令简介及教程
- EBS功能_Oracle ERP系统借贷关系
- 指纹识别零日攻击的仿真器
- “21 天好习惯”第一期-7
- codevs 2905 足球晋级
- php仿制网站,如何仿制网站(一模一样),制造后台管理系统CMS
- Toncat环境变量的配置
- 我用20种编程语言送上新年的祝福,Happy new year!
- 朋友、心情与父子、亲情
热门文章
- 中国人工智能学会通讯——融合经济学原理的个性化推荐
- 信息安全产业爆发在即 十三五年均增长将达20%以上
- phpcmsv9 更换域名出现页面无法访问后怎么办
- Android 中自定义控件和属性(attr.xml,declare-styleable,TypedArray)的方法和使用 一
- 我今天学习的技术,明天会不会一钱不值
- Java咖啡馆(8)——大话面向对象(下)
- 3.业务架构·应用架构·数据架构实战 --- 战略驱动的业务架构设计
- 20.高性能MySQL --- 在MySQL上使用 Sphinx
- mysql 批量更新_MySQL批量更新
- sql中用于子查询的几个关键词 any(some是 any的别名),all,in,exists