C与C++混合编程

C++ 是在 C 语言的基础上发展起来的。在某种程度上,我们可将 C++ 看做 C 的一种扩展。在本质上,二者的数据类型和函数调用惯例都是一致的,因此 C 与 C++ 混合编译也是很自然的事情。

二者的区别仅在于编译后函数的名字不同──C 简单地使用函数名而不考虑参数的个数或类型,而 C++ 编译后的函数名则总是将参数类型列表作为其一部分。尽管如此,C++ 提供了特殊的机制来声明 C 函数,这意味着一个 C++ 程序可以直接声明和调用 C 函数。

C++调用C函数

下面是 C++ 程序调用 C 函数 csayhello() 的一个例子。由于该函数在 C++ 程序内声明时使用了 extern "C",故调用可以直接进行:

/* cpp2c.cpp */
#include <iostream>
extern "C" void csayhello(char *str);
int main(int argc,char *argv[])
{
csayhello("Hello from cpp to c");
return();
}

C 函数不需任何特殊处理,其代码如下:

/* csayhello.c */
#include <stdio.h>
void csayhello(char *str)
{
printf("%s\n",str);
}

下面三条命令编译以上两个文件并将二者链接为一个可执行文件。由于 gcc 和 g++ 的灵活性使得存在很多方法来完成该任务,但这三条命令或许是最常用的:

$ g++ -c cpp2c.cpp -o cpp2c.o
$ gcc -c csayhello.c -o csayhello.o
$ gcc cpp2c.o csayhello.o -lstdc++ -o cpp2c

注意到,在最后链接的时候指定 C++ 标准库是必须的,这是因为我们用的是 gcc 而不是 g++ 调用的链接器。如果使用的是 g++ 的话,C++ 标准库默认会被链接。

最普遍的做法是,将函数声明放到头文件中,然后将所有内容包含在 extern "C" 声明块内。文件内容像下面所示:

extern "C" {
int mlimitav(int lowend, int highend);
void updatedesc(char *newdesc);
double getpct(char *name);
};

C调用C++函数

要使 C 程序能够调用 C++ 中函数的话,C++ 提供一个符合 C 调用惯例的函数是必须的。下面的例子演示了在 C++ 内创建 C 函数的语法:

/* cppsayhello.cpp */
#include <iostream>
extern "C" void cppsayhello(char *str);
void cppsayhello(char *str)
{
std::cout << str << "\n";
}

尽管函数 cppsayhello() 通过 extern "C" 声明为 C 函数,事实上它是 C++ 源代码的一部分,这意味着函数体内是真正的 C++ 代码。在函数内你可以自由地创建和析构对象。如果你要在 cppsayhello() 内调用 C 函数的话,将其声明为 extern "C" 是必须的。否则,编译器会将作为一个 C++ 函数并相应地更改函数名。

下面是调用 C++ 函数 cppsayhello() 的 C 程序:

/* c2cpp.c */
int main(int argc,char *argv[])
{
cppsayhello("Hello from C to C++");
return();
}

下面的命令编译并链接生成c2cpp:

$ g++ -c cppsayhello.cpp -o cppsayhello.o
$ gcc -c c2cpp.c -o c2cpp.o
$ gcc cppsayhello.o c2cpp.o -lstdc++ -o c2cpp

简单一句话理解,extern C 告诉编译器该函数需要用C的方式来链接。

C++/C混合编程的更多相关文章

  1. 如玫瑰一般的PHP与C#混合编程

    故事背景是这样的,有一套项目,服务器端是用C#写的,为了完成某种事情,它需要使用到一个组件,这个组件很小但很重要,很不巧的是,这个这个组件是用PHP语言写的,如果为了使用这个组件而专门搭建一个PHP的 ...

  2. C和C++混合编程中的extern "C" {}

    引言 在用C++的项目源码中,经常会不可避免的会看到下面的代码: 1 2 3 4 5 6 7 8 9 #ifdef __cplusplus extern "C" { #endif ...

  3. C# 托管和非托管混合编程

    在非托管模块中实现你比较重要的算法,然后通过 CLR 的平台互操作,来使托管代码调用它,这样程序仍然能够正常工作,但对非托管的本地代码进行反编译,就很困难.   最直接的实现托管与非托管编程的方法就是 ...

  4. [转载:]C#与Fortran混合编程之本地调用Fortran动态链接库

    前言 C#发展到现在,已是一门相当完善的语言,他基于C语言风格,演化于C++.并依靠强大的.NET底层框架.C#可以用来快速构建桌面及Web应用.然而在我们的实际工作中,尽管C#已经非常完善,但还是不 ...

  5. C#Matlab混合编程类 初始化问题解决方法

    ************** 异常文本 ************** System.TypeInitializationException: “myPlus.matClass”的类型初始值设定项引发异 ...

  6. 国内第一部C#.Net调用Matlab混合编程视频教程

       本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新 Matlab和C#混合编程文章目录:[目录]Matlab和C#混合编程文章目录 一.视频说明 2014年的5.1,我将这套视频教 ...

  7. 【5.1送礼】国内第一部Matlab和C#.Net混合编程视频教程【免费】

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 上一次写博客很久了 ...

  8. 【原创】Matlab.NET混合编程技巧之找出Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 Matlab与.N ...

  9. 【原创】Matlab.NET混合编程技巧之直接调用Matlab内置函数

                  本博客所有文章分类的总目录:[总目录]本博客博文总目录-实时更新    Matlab和C#混合编程文章目录 :[目录]Matlab和C#混合编程文章目录 在我的上一篇文章[ ...

  10. 【目录】Matlab和C#混合编程文章目录

    本博客所有文章分类的总目录链接:[总目录]本博客博文总目录-实时更新 1.Matlab和C#混合编程文章目录 9.接触Matlab10年后的一个总结,随时使用Matlab要掌握的一些要点 8.国内第一 ...

随机推荐

  1. Qt笔记——入门

    Qt的介绍 跨平台c++图形用户界面应用程序框架 Qt的框架 父类(基类)子类(派生类) 头文件 QApplication应用程序类 Qt头文件没有.h 头文件和类名一样 有且只有一个应用程序类的对象 ...

  2. PHP常用函数及其注释

    <?php //===============================时间日期=============================== //y返回年最后两位,Y年四位数,m月份数字 ...

  3. NAT+穿洞基础知识梳理

    参考:https://www.cnblogs.com/shilxfly/p/6589255.html https://blog.csdn.net/phoenix06/article/details/7 ...

  4. HDU 1061.Rightmost Digit-规律题 or 快速幂取模

    Rightmost Digit Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  5. ACM数论-欧几里得与拓展欧几里得算法

    欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数. 基本算法:设a=qb+r,其中a,b,q,r都是整数,则gcd(a,b)=gcd(b,r),即gcd(a,b)=gcd(b,a%b). ...

  6. SPOJ PT07J - Query on a tree III(划分树)

    PT07J - Query on a tree III #tree You are given a node-labeled rooted tree with n nodes. Define the ...

  7. 对mysql 数据库操作 使其支持插入中文(针对python)

    首先,这项任务确切的说需要三步吧: #1.建立数据库(数据库名为xsk) create database `xsk` character set 'utf8' collate 'utf8_genera ...

  8. [Contest20180328]同构

    我们先把两棵树的所有节点的儿子排序,然后dfs,记录访问的深度序列 然后可以发现题目中的两个操作都只会在深度序列中删掉一位,不会对其他位有影响(自己画画图就知道了) 对于一个深度序列$d_{1\cdo ...

  9. Problem W: 零起点学算法21——求平均值

    #include<stdio.h> int main() { int a,b,c; scanf("%d %d %d",&a,&b,&c); pr ...

  10. Problem S: 零起点学算法14——三位数反转

    #include<stdio.h> #include<stdlib.h> int main() { int a,b,c,s; scanf("%d",& ...