extern “C”调用测试与验证-2015.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 0;
}

使用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变成[email protected]@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 0;
}

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函数被命名为[email protected]@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编译的命名规则,因此,可以编译链接通过。

时间: 2024-12-23 13:25:09

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

2015.01.06 JQuery

jQuery是一个兼容多浏览器的javascript库.开发出来的JavaScript的脚本包.非侵入性的脚本. 1.找对象.基本的结构. 1 $(document).ready(function () { 2 // 写代码 3 //HTML文档在浏览器中加载完成时触发. 4 }); 选择器: 一.基本选择器 标签选择器. class选择器. ID选择器. 逗号隔开——并列 空格隔开——后代 >号隔开——子级选择

业界顶级存储IO 性能分析工具Iometer 2015.01.23A1版本(基于2014年1.1.0版本)

篇首语 在存储界浪迹几年的人,或多或少都使用过一款或多款IO 测试工具来说明某款存储产品或者存储系统的性能表现.主流的存储厂商,在售前产品比拼测试阶段,客户一般都需要竞标者提供一些测试数据,而这些测试数据最好采用同一款第三方工具,基于相同的标准.迄今为止,这些工具中比较著名的有Iometer.Iozone.fio.vdbench 等. 笔者曾经有一段时间使用过Iometer,后来因为其支持平台类型过于狭窄而放弃.在去年的一个北美SDN项目中,由于需要进行性能数据比较,同时为便于北美工程师可以协同

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

转自:http://blog.csdn.net/u012995964/article/details/54562111 本文记录带有SoapHeader验证的WebServices服务创建.部署及C#中的静态调用方法,基于 Windows8.1.Visual Studio 2013.IIS8 环境实现. WebServices服务创建 Visual Studio 2013中创建WebServices 创建一个空的 ASP.NET Web 应用程序 : 创建 WebService 服务的程序(as

轻松把玩HttpClient之封装HttpClient工具类(四),单线程调用及多线程批量调用测试

本文主要来分享一下该工具类的测试结果.工具类的整体源码不再单独分享,源码基本上都已经在文章中了.开始我们的测试. 单线程调用测试: public static void testOne() throws HttpProcessException{ System.out.println("--------简单方式调用(默认post)--------"); String url = "http://tool.oschina.net/"; //简单调用 String re

支持APP手机应用(android和ios)接口调用 ,传输验证可用 shiro 的 MD5、SHA 等加密

请认准本正版代码,售后技术有保障,代码有持续更新.(盗版可耻,违者必究)         此为本公司团队开发 ------------------------------------------------------------------------------------------------------------------------- 1. 有 oracle .msyql.spring3.0.spring4.0  一共 4 套版本全部提供没有打jar没有加密的源代码(最下面截图2

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

注:本文来自hacpai.com:Tanken的<纯 Java 开发 WebService 调用测试工具(wsCaller.jar)>的文章 基于 Java 开发的 WebService 测试工具,不像上文的 iWallpaper.jar 只能实现在 Windows 系统下的功能,此工具发挥了 Java 跨平台的优势,亲测可在 Windows.Mac OS 及 Linux 下运行及使用.简单易用的专门用于测试 WebService 的小工具,在 2003 版 wsCaller.jar 的基础上

storm1.1.0 drpc 部署和调用测试

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

【2015/01/28】QQ徽章墙通用破解补丁(理论支持目前所有版本)

[软件介绍:]软件名称:QQ徽章墙通用补丁软件版本:1.1软件语言:简体中文更新日期:2015.01.28软件制作:Mrack软件大小:9.33 KB (9,561 字节)CRC32:FBD44EADMD5:904349422A9D60F85489789A07C7A23D┏-----------------------------------------┓             QQ徽章墙全版本通杀         请在24小时内删除本补丁   如有私自传播造成纠纷,本人概不负责.------

callback调用测试

<html> <head> <script> var context="全局"; var testObj={ context:"初始", callback:function (str){//回调函数 alert("callback:我所处的上下文中,context="+this.context+",我被回调的方式:"+str); }, caller:function(){ callWithC