如下代码:

/*C语言头文件:Max.h*/

#ifndef _MAX_H_

#define _MAX_H_

int Max(int nA,int nB)

#endif

/*C语言实现文件:Max.c*/

#include "Max.h"

int Max(int nA,int nB)

{

  return((nA-nB)?(nA):(nB));

}

/*C++语言调用文件*/

#include "Max.h"

int _tmain(int argc,char* argv[])

{

  int nMax = Max(1,2);

  return 0;

}

上述代码在Visual C++中编译会出错(error LNK2019:无法解析的外部符号"int __cdecl Max(int,int)"(?Max@@YAHHH@Z),该符号在函数_wmain中被引用

如果把上述的Max.h代码修改如下:

/*C语言头文件*/

#ifndef __MAX_H__

#define __MAX_H__

#ifdef __cplusplus

extern "C"{

#endif

  int Max(int nA,int nB);

#ifdef __cplusplus

};

#endif

#endif

编译通过

结论:在C++中调用C的代码必须把原来的C语言声明放到extern "C"{/*code*/}中,否则在C++中无法编译通过

原因:C和C++具有完全不同的编译和链接方式。C语言编译器编译函数时不带函数的类型和作用域信息,只包含函数符号名字;而c++编译器为了实现函数的重载,在编译时会带上函数的类型和作用域信息。

例如:假如某一函数原型为:int Func(int nA,int nB)

C语言编译器把函数编译成类似_Func的符号,C链接器只要找到这个符号就可以连接成功,实现调用。而在C++语言中,编译器会检查参数类型和作用域信息,上述函数原型会编译成_Z_Func_int_int这样的符号。在链接过程中,C++链接器会在函数原型所在模块生成的目标文件中查找__Z_Func_int_int.

总结:C++中调用C代码的3种具体实现方式

1.修改C代码的头文件,当其被用于C++代码时,在声明中加入exter "C"    上例中在Max.h中加入extern "C" int Max(int nA,int nB);

2.在C++代码中(Main.cpp)重新声明一下C函数,在重新声明时添加extern "C".

#include "Max.h"

extern "C" int Max(int nA,int nB);

3.在包含C头文件(Main.cpp)时,添加extern "C".

extern "C"{

#include "Max.h"

}

注意:extern "C" 一定要加在C++的代码文件中才起作用

在C++中如何使用C的更多相关文章

  1. Python开源框架

    info:更多Django信息url:https://www.oschina.net/p/djangodetail: Django 是 Python 编程语言驱动的一个开源模型-视图-控制器(MVC) ...

  2. mapreduce中一个map多个输入路径

    package duogemap; import java.io.IOException; import java.util.ArrayList; import java.util.List; imp ...

  3. Hadoop 中利用 mapreduce 读写 mysql 数据

    Hadoop 中利用 mapreduce 读写 mysql 数据   有时候我们在项目中会遇到输入结果集很大,但是输出结果很小,比如一些 pv.uv 数据,然后为了实时查询的需求,或者一些 OLAP ...

  4. Python中的多进程与多线程(一)

    一.背景 最近在Azkaban的测试工作中,需要在测试环境下模拟线上的调度场景进行稳定性测试.故而重操python旧业,通过python编写脚本来构造类似线上的调度场景.在脚本编写过程中,碰到这样一个 ...

  5. .NET Core中的认证管理解析

    .NET Core中的认证管理解析 0x00 问题来源 在新建.NET Core的Web项目时选择“使用个人用户账户”就可以创建一个带有用户和权限管理的项目,已经准备好了用户注册.登录等很多页面,也可 ...

  6. Angular杂谈系列1-如何在Angular2中使用jQuery及其插件

    jQuery,让我们对dom的操作更加便捷.由于其易用性和可扩展性,jQuer也迅速风靡全球,各种插件也是目不暇接. 我相信很多人并不能直接远离jQuery去做前端,因为它太好用了,我们以前做的东西大 ...

  7. 关于CryptoJS中md5加密以及aes加密的随笔

    最近项目中用到了各种加密,其中就包括从没有接触过得aes加密,因此从网上各种查,官方的一种说法: 高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学 ...

  8. In-Memory:在内存中创建临时表和表变量

    在Disk-Base数据库中,由于临时表和表变量的数据存储在tempdb中,如果系统频繁地创建和更新临时表和表变量,大量的IO操作集中在tempdb中,tempdb很可能成为系统性能的瓶颈.在SQL ...

  9. SQL Server中的高可用性(2)----文件与文件组

        在谈到SQL Server的高可用性之前,我们首先要谈一谈单实例的高可用性.在单实例的高可用性中,不可忽略的就是文件和文件组的高可用性.SQL Server允许在某些文件损坏或离线的情况下,允 ...

  10. 【.net 深呼吸】序列化中的“引用保留”

    假设 K 类中有两个属性/字段的类型相同,并且它们引用的是同一个对象实例,在序列化的默认处理中,会为每个引用单独生成数据. 看看下面两个类. [DataContract] public class 帅 ...

随机推荐

  1. Android 使用Jsoup解析Html

    想要做一个看新闻的应用,类似Cnbeta客户端的东西.大致思路如下:根据链接获取新闻列表页的html代码,然后解析,找到所有的新闻标题和新闻链接用listView显示,当点击ListView的Item ...

  2. 【虚拟化实战】容灾设计之四VPLEX

    作者:范军 (Frank Fan) 新浪微博:@frankfan7 VPLEX等存储设备的出现,可以实现双活数据中心,最大程度的有效利用运算和存储资源. 在“容灾设计之三Stretched Clust ...

  3. 【转】stdin, stdout, stderr 以及重定向

    详细见: http://my.oschina.net/qihh/blog/55308 stdin是标准输入文件,stdout是标准输出文件,stderr标准出错文件. 程序按如下方式使用这些文件: 标 ...

  4. 通过案例练习掌握SSH 的整合

    1. SSH整合_方案01 **  整合方案01  Struts2框架 Spring框架  在Spring框架中整合了Hibernate(JDBC亦可)  一些业务组件(Service组件)也可以放入 ...

  5. HDU 3123-GCC(递推)

    GCC Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Subm ...

  6. Html5 自定义数据属性

    html5 可以为元素添加自定义属性,但是要添加前缀data-.(下面这个例子中的自定义属性的命名,其实是不规范的,不应该包含大写字符,例如:data-myName 应改命名为:data-myname ...

  7. C# 第三方控件 下面的Item不显示了

    当高版本的第三方版本 替换成低版本的第三方后,item,不显示了之后,请试着再次在这基础上添加一个Item,观察这个Item和原来已经在的却不显示的Item的区别在哪里.然后去源程序正常文件哪里 将这 ...

  8. LDAP验证用户名和密码

    测试环境:VS2008, NET Framework 3.5 公司打算改用LDAP来存储用户名和密码,现在用C#测试下如何能拿到LDAP中的用户名,并检测用户密码是否正确.即输入用户名和密码,可以检验 ...

  9. javaTemplates-学习笔记二

    配置PlayFramework环境 下载jar包[Play with Activator],这一步有点晕是JAVA程序员CMD执行的步骤;运行了jar包下载了很多配置文件什么的,有的资源没有VPN链接 ...

  10. 2)PHP中把读取.txt中内容并转为UTF-8格式

    <?php $filename = "filename.txt"; $handle = fopen($filename, "r");//读取二进制文件时, ...