extern “C”调用测试与验证-2016.01.06
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的更多相关文章
- 猿题库 iOS 客户端架构设计(原文地址:http://gracelancy.com/blog/2016/01/06/ape-ios-arch-design/)
猿题库 iOS 客户端架构设计 序 猿题库是一个拥有数千万用户的创业公司,从2013年题库项目起步到2015年,团队保持了极高的生产效率,使我们的产品完成了五个大版本和数十个小版本的高速迭代.在如此快 ...
- 钉钉的收费 [钉钉深圳研发团队 denny/2016.01.06/ 59888745@qq.com]
普通用户(个人) 团队 企业 1.免费额度为每月通话100分钟.每天发DING 5次. 1. 每月通话300分钟,每天发DING 10次. 2. 群组最多可达1500人 1. 该公司所 ...
- [官方软件] 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 ...
- C#动态调用带有SoapHeader验证的WebServices
http://blog.csdn.net/u012995964/article/details/54573143 本文记录C#中通过反射动态的调用带有SoapHeader验证的WebServices服 ...
- C#静态调用带有SoapHeader验证的WebServices
转自:http://blog.csdn.net/u012995964/article/details/54562111 本文记录带有SoapHeader验证的WebServices服务创建.部署及C# ...
- callback调用测试
<html> <head> <script> var context="全局"; var testObj={ context:"初始& ...
- storm1.1.0 drpc 部署和调用测试
一.配置集群storm.yaml文件,配置drpc.server 二.部署到linux上,开启nimbus,drpc,supervisor 等服务 /opt/module/storm-1.1.0/bi ...
- 纯 Java 开发 WebService 调用测试工具(wsCaller.jar)
注:本文来自hacpai.com:Tanken的<纯 Java 开发 WebService 调用测试工具(wsCaller.jar)>的文章 基于 Java 开发的 WebService ...
- extern “C”原理,用法以及使用场景-2016.01.05
1 问题提出 在编程过程中,经常发现如下用法: #ifndef _FILE_NAME_H_ #define _FILE_NAME_H_ #ifdef __cplusplus extern " ...
随机推荐
- (C/C++) Interview in English - Class
Q: What is a class? A: A class is an expanded concept of a data structure: instead of holding only d ...
- jquery.cookie.js存与取以及过期时间设置
$(function(){ $(".active_out .abtn").click(function(){ $(this).parents(".active_out&q ...
- PLSQL_性能优化工具系列09_SQL Plan Management
2014-09-24 Created By BaoXinjian
- Axis2/c 知识点
官网文档: http://axis.apache.org/axis2/c/core/docs/axis2c_manual.html 从文档中可以总结出: 1. Axis2/C是一个用C语言实现的We ...
- JAVA 方法重载
方法的重载是指:一个类中可以定义有相同的名字,但参数不同的多个方法,调用时会根据不同的参数列表选择对应的方法. 实例: W.java public class W{ public void F(Str ...
- IronPython调用C# DLL函数方法
C# DLL源码 using System; using System.Collections.Generic; using System.Text; using System.Security.Cr ...
- WCF bindings comparison z
Binding Protocol/Transport Message Encoding Security Default Session Transaction Duplex BasicHttpBin ...
- android 插件化 模块化开发
http://blog.csdn.net/o1587790525/article/details/11891997 Android 插件化架构设计 http://www.iqiyi.com/w_19 ...
- [ZOJ 1002] Fire Net (简单地图搜索)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1002 题目大意: 给你一个n*n的地图,地图上的空白部分可以放棋 ...
- Oracle 删除数据后释放数据文件所占磁盘空间
测试的时候向数据库中插入了大量的数据,测试完成后删除了测试用户以及其全部数据,但是数据文件却没有缩小.经查阅资料之后发现这是 Oracle “高水位”所致,那么怎么把这些数据文件的大小降下来呢?解决办 ...