1 调用情形说明

在上一篇关于extern “c”原理以及用法中,详细的说明了为什么需要extern “c”以及如何使用它解决c与c++混合编程时遇到的问题。接下来,使用示例验证方式验证c与c++函数在加入extern “c”和未加入extern “c”修饰下,函数编译以及链接时,函数命名的各种情形。主要形成如下几种情形:

1、c函数调用c函数,不使用extern “c”修饰

2、c函数调用c函数,使用extern “c”修饰,其实本质与1相同,因为只有c函数调用,因此不存在定义了__cplusplus的宏,extern “c”修饰不起作用

3、c++函数调用c函数,不使用extern “c”修饰

4、c++函数调用c函数,使用extern “c”修饰

5、c++调用c++函数,不使用extern “c”修饰

6、c++调用c++函数,使用extern “c”修饰

7、c调用c++函数,不使用extern “c”修饰

8、c调用c++函数,使用extern “c”修饰

编译环境Visual Studio 2010,函数文件说明:c函数头文件和源文件分别命令为c.h和c.c,c++函数头文件和源文件命名为cpp.h和cpp.cpp,c调用文件命令为example.c,c++调用文件命令为example.cpp。

1 c函数调用c函数,不使用extern “c”修饰

文件结构视图

其中c.h文件内容

#ifndef _c_h_
#define _c_h_
void c_fun();
#endif

c.c文件内容

#include "c.h"
#include <stdio.h> void c_fun()
{
printf("this is c function\n");
}

example.c文件内容

#include "c.h"

int main()
{
c_fun();
return ;
}

使用dumpbin查看编译后的obj文件,c.obj符号表信息如下:

其中,c_fun编译后函数名称为_c_fun。

example.ojb符号表信息如下:

调用链接时,main函数链接的函数名同样也是_c_fun,因此,c函数调用c函数,编译链接都使用c命名规则。

2 c函数调用c函数,使用extern “c”修饰

将情形1中的c.h头文件添加extern “c”修饰,具体如下:

#ifndef _c_h_
#define _c_h_
#ifdef __cplusplus
extern "C" {
#endif void c_fun(); #ifdef __cplusplus
}
#endif
#endif

c.ojb符号表信息如下:

与情形1中c.obj符号表信息一致。因为,情形2其实本质与1相同,因为只有c函数调用,因此不存在定义了__cplusplus的宏,extern “c”修饰不起作用

3 c++函数调用c函数,不使用extern “c”修饰

与情形1保持所有文件内容不变,仅将调用文件example.c文件名修改成example.cpp

上述可用编译通过,但链接不通过,提示找不到如下的符号信息:

查看example.obj符号表信息:

在example.ojb符号表信息中,看到_main函数调用c_fun函数名称已经有情形1中的_c_fun变成?c_fun@@YAXXZ,而在c.obj中,c_fun函数名仍然为_c_fun,因此无法链接成功。

4 c++函数调用c函数,使用extern “c”修饰

在情形3基础上,在c.h头文件中,添加extern “C”修饰,告知c++编译不要使用c++编译规则编译,而是使用c编译规则。

c.h文件具体如下:

#ifndef _c_h_
#define _c_h_
#ifdef __cplusplus
extern "C" {
#endif void c_fun(); #ifdef __cplusplus
}
#endif
#endif

查看example.obj符号表信息:

可用看到,使用extern “c”修饰后,在_main函数中链接的符号信息为按照c编译规则命名的_c_fun,因此,可以编译链接通过。

5 c++调用c++函数,不使用extern “c”修饰

文件结构视图:

cpp.h头文件内容:

#ifndef _cpp_h_
#define _cpp_h_ void cpp_fun(); #endif

cpp.cpp源文件内容:

#include "cpp.h"
#include <stdio.h> void cpp_fun()
{
printf("this is c++ function\n");
}

example.cpp调用文件内容:

#include "cpp.h"

int main()
{
cpp_fun();
return ;
}

cpp.obj符号表信息:

example.obj符号表信息:

从上述的符号表信息可用看出,编译使用的c++的编译命名规则。

6 c++调用c++函数,使用extern “c”修饰

除了在cpp.h头文件中添加extern “c”修饰外,其他文件内容以及文件结构与情形5保持一致。

cpp.h文件内容如下:

#ifndef _cpp_h_
#define _cpp_h_ #ifdef __cplusplus
extern "C" {
#endif void cpp_fun(); #ifdef __cplusplus
}
#endif #endif

cpp.obj符号表信息:

example.obj符号表信息:

从上述符号表信息看出,使用extern “c”修饰后,编译链接使用的是c编译命名规则。

7 c调用c++函数,不使用extern “c”修饰

文件内容与情形5保持一致,仅将example.cpp文件名称修改成example.c,具体如下:

cpp.obj符号表信息:

example符号表信息:

在链接过程中,_main函数中链接的函数信息为_cpp_fun,而在cpp.obj符号表信息中cpp_fun函数被命名为?cpp_fun@@YAXXZ,因此出现如下的链接错误。

8 c调用c++函数,使用extern “c”修饰

在情形7的基础上,在cpp.h头文件中添加extern “c”修饰,具体代码如下:

#ifndef _cpp_h_
#define _cpp_h_ #ifdef __cplusplus
extern "C" {
#endif void cpp_fun(); #ifdef __cplusplus
}
#endif #endif

cpp.obj符号表信息:

example.obj符号表信息:

从上述符号表信息可以看出,编译链接均采用c编译的命名规则,因此,可以编译链接通过。

extern “C”调用测试与验证-2016.01.06的更多相关文章

  1. 猿题库 iOS 客户端架构设计(原文地址:http://gracelancy.com/blog/2016/01/06/ape-ios-arch-design/)

    猿题库 iOS 客户端架构设计 序 猿题库是一个拥有数千万用户的创业公司,从2013年题库项目起步到2015年,团队保持了极高的生产效率,使我们的产品完成了五个大版本和数十个小版本的高速迭代.在如此快 ...

  2. 钉钉的收费 [钉钉深圳研发团队 denny/2016.01.06/ 59888745@qq.com]

    普通用户(个人) 团队 企业 1.免费额度为每月通话100分钟.每天发DING 5次. 1.   每月通话300分钟,每天发DING   10次. 2.   群组最多可达1500人 1.   该公司所 ...

  3. [官方软件] Easy Sysprep v4.3.29.602 【系统封装部署利器】(2016.01.22)--skyfree大神

    [官方软件] Easy Sysprep v4.3.29.602 [系统封装部署利器](2016.01.22) Skyfree 发表于 2016-1-22 13:55:55 https://www.it ...

  4. C#动态调用带有SoapHeader验证的WebServices

    http://blog.csdn.net/u012995964/article/details/54573143 本文记录C#中通过反射动态的调用带有SoapHeader验证的WebServices服 ...

  5. C#静态调用带有SoapHeader验证的WebServices

    转自:http://blog.csdn.net/u012995964/article/details/54562111 本文记录带有SoapHeader验证的WebServices服务创建.部署及C# ...

  6. callback调用测试

    <html> <head> <script> var context="全局"; var testObj={ context:"初始& ...

  7. storm1.1.0 drpc 部署和调用测试

    一.配置集群storm.yaml文件,配置drpc.server 二.部署到linux上,开启nimbus,drpc,supervisor 等服务 /opt/module/storm-1.1.0/bi ...

  8. 纯 Java 开发 WebService 调用测试工具(wsCaller.jar)

    注:本文来自hacpai.com:Tanken的<纯 Java 开发 WebService 调用测试工具(wsCaller.jar)>的文章 基于 Java 开发的 WebService ...

  9. extern “C”原理,用法以及使用场景-2016.01.05

    1 问题提出 在编程过程中,经常发现如下用法: #ifndef _FILE_NAME_H_ #define _FILE_NAME_H_ #ifdef __cplusplus extern " ...

随机推荐

  1. Form_Form与OAF页面互相调用(案例)

    2014-12-27 Created By BaoXinjian

  2. centos6配置远程桌面,使用xmanager访问

    现在linux的图形界面越来越丰富,使用图形界面操作也逐渐成为使用者的一种习惯.在我们安装文件的过程中,经常会应用得到. 比如远程安装oracle,或者有多台主机.避免在不同主机间切换显示器. 1.检 ...

  3. python(8) 自己制造异常让程序退出,把print的内容写入到文件

    异常 也可以自己输出异常原因: raise Exception("404 404 404") import math import time #print 到文件的代码****** ...

  4. [物理学与PDEs]第4章习题参考解答

    [物理学与PDEs]第4章习题1 反应力学方程组形式的化约 - 动量方程与未燃流体质量平衡方程 [物理学与PDEs]第4章习题2 反应力学方程组形式的化约 - 能量守恒方程 [物理学与PDEs]第4章 ...

  5. [物理学与PDEs]第5章习题参考解答

    [物理学与PDEs]第5章习题1 矩阵的极分解 [物理学与PDEs]第5章习题2 Jacobian 的物质导数 [物理学与PDEs]第5章习题3 第二 Piola 应力张量的对称性 [物理学与PDEs ...

  6. 读《java核心技术卷一》有感

    过去一个多月了吧.才囫囵吞枣地把这书过了一遍.话说这书也够长的,一共706页.我从来不是个喜欢记录的人,一直以来看什么书都是看完了就扔一边去,可能有时候有那么一点想记录下来的冲动,但算算时间太紧,很多 ...

  7. VI下删除所有内容

    让光标在一个位置 , 如果全删就放在问价开始的位置 , 在非编辑的状态下输入dG(注意大小写) , 这样光标之后的所有行都会被删掉

  8. CSS媒体查询,CSS根据不同的分辨率显示不同的样式

    在写自适应网页的时候,我们需要网页有几种显示方式,我们可以用CSS实现这个功能 使用CSS提供的媒体查询,我们可以根据屏幕分辨率来使用相应的CSS样式 @media screen and (max-w ...

  9. 使用Topshelf 5步创建Windows 服务 z

    使用Topshelf创建Windows 服务简要的介绍了创建Windows服务的另一种方法,老外的一篇文章Create a .NET Windows Service in 5 steps with T ...

  10. JavaScript【面向对象】-静态方法-私有方法-公有方法-特权方法

    JavaScript面向对象是近年来比较火的一个概念了,由于小弟才疏学浅,虽然做过不少的web项目,看了网上很多深奥的资料和教程,还是对他们深奥 的理论一知半解,前段时间看了点书,总算有了自己的理解, ...