Linux下C调用C++接口详解

    C++做久了,经常用C++的方式去思考问题,有时候就突然发现自己不太会写C程序了。写程序的时候,难免会用到第三方插件或者是库,而这些插件或者库很多时候都不能完全满足我们的需求,遇到这种情况,如果全是C++,那好办,写个适配器就OK了,关于适配器模式参考我的博客《C++ Adaptor 设计模式》    如果要提供给C程序使用,那就需要自己封装C程序可以使用的库。前几天在CSDN Linux/Unix版闲逛的时候,遇到一位网友,他问这样的问题:(原话我记不住了,大致是这个意思)我要要封装一个C++接口提供给C程序使用,C++程序完全没有问题,可以运行,但是封装的时候,我使用g++编译,就没问题,但是预期的结果是使用gcc编译程序,可是使用gcc编译的时候确保错,很多 undefined...我想熟悉Linux编程的人一看这个问题都知道是怎么回事。这里我就不标新立异了,我只想总结下如果让C调用C++接口

         再将接口封装之前先将建C/C++的一些特性有助于后面的理解。

        C++创始人在编写C++的时候,C语言正盛行,他不得不让C++兼容C。C++最大的特性就是封装,继承,多态,重载。而这些特性恰恰是C语言所不具备的。至于多态,核心技术是通过虚函数表实现的,其实也就是指针。而对于重载,与C语言相比,其实就是编译方式不同而已: C++编译方式和C编译方式。对于函数调用,编译器只要知道函数的参数类型和返回值以及函数名就可以进行编译连接。那么为了让C调用C++接口或者是说C++调用C接口,就必须是调用者和被调用者有着同样的编译方式。这既是extern "C"的作用,extern “C”是的程序按照C的方式编译。我们先来看看C++和C两种编译方式对于究竟有何不同,由于C只考虑函数调用,这里只讨论函数的差别。下来看一段源代码:

我们用一个很简短的代码说明问题:

//cplus.cpp
//按照C++方式编译程序
int Operation(int)

键入命令编译cplus: g++ -c cplus.cpp -o cplus.o 产生了目标文件cplus.o。我们来看看该目标文件中的符号

使用nm命令查看内部符号:nm cplus.o

内容很简单:00000000 T _Z9Operationi

再来看看加 exern "C"按照C方式编译程序:

extern "C"
int Operation(int)

同样使用上面的命令产生cplus.o。然后查看符号如下:

00000000 T Operation

对比下可以发现,使用C++方式编译函数多了个_Z9前缀和i后缀,其中i指的是参数类型。这下明白了,因为C不存在重载,只需要知道函数名称就可以确定函数,而C++有重载,需要根据参数类型和返回类型才可以唯一确定一个函数。

    说道这里,大家估计已经理解的差不多了。提供给C的接口必须加 extern "C"。这里还只是确定了编译方式,extern "C"只能让编译器安C的方式编译。但是C并不认识

extern "C",这里还要加一道工序:在C文件中 extern下接口。这样C程序就认识接口函数了。下面以一个简单的例子来说明具体如何让封装C++接口给C使用。

//myclass.h
#include <iostream>
using namespace std;

class Myclass
{
    public:
        Myclass(){}
        ~Myclass(){}
        void Operation();

};

//myclass.cpp
extern "C"
void Myclass::Operation
{
    cout << "Hi, Harlen" << endl;
}

编译命令:g++ -c myclass.cpp -o myclass.o

//interface.cpp

#include "myclass.h"

void interface()
{
	Myclass obj;
	obj.Operation();
}

编译命令:g++ -c interface.cpp -o interface.o

这样,其实接口就已经准备好了。一种方式是使用命令:ar rs libinterface.a interface.o myclass.o产生静态库提供接口。

另一种方式是使用gcc,将调用程序的.o目标文件和myclass.o, interface.o一起编译成可执行程序。

//main.c
extern interface();

int main(int argc, char**argv)
{
    interface()
}

编译:gcc -c main.c -o main.o

:gcc -o main interface.o myclass.o -lstdc++到此为止,接口已经提供完成。C程序中就可以使用interface接口了。

时间: 2024-10-14 21:07:03

Linux下C调用C++接口详解的相关文章

Linux下Android ADB驱动安装详解

Linux下Android ADB驱动安装详解 概述 最近由于内置的合作商比较多,本人使用的Ubuntu系统好多厂商的Android手机都无法正确的识别,经过一番折腾,和查阅SDK,现把Linux下ADB驱动配置的方法和当中会遇到的相关问题的解决方法整理出来贡献给大家. Linux下使用手机USB调试模式连接ADB进行Android程序的调试,配置驱动没有Windows来的直观. 具体步骤 首先确认手机连接上电脑,lsusb查看下设备记录. matthew@matthew-1230-laptop

Linux下的压缩解压缩命令详解

linux zip命令 zip -r myfile.zip ./*将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. 2.unzipunzip -o -d /home/sunny myfile.zip把myfile.zip文件解压到 /home/sunny/-o:不提示的情况下覆盖文件:-d:-d /home/sunny 指明将文件解压缩到/home/sunny目录下: 3.其他zip -d myfile.zip smart.txt删除压缩文件中

Linux下多线程中的信号处理详解教程

在linux下,每个进程都有自己的signal mask,这个信号掩码指定哪个信号被阻塞,哪个不会被阻塞,通常用调用sigmask来处理.同时每个进程还有自己的signal action,这个行为集合指定了信号该如何处理,通常调用sigaction来处理. 使用了多线程后,便有些疑问: 信号发生时,哪个线程会收到是不是每个线程都有自己的mask及action每个线程能按自己的方式处理信号么 首先,信号的传递是根据情况而定的: 如果是异常产生的信号(比如程序错误,像SIGPIPE.SIGEGV这些

linux下配置yum源方法详解_Linux

本人使用的方法一,成功配置,方法二没测过,可以作为参考 方法一: 1.确保RHEL5中已经安装了yum [root@lvs-master ~]# rpm -qa |grep yum yum-metadata-parser-2-el5 yum-updatesd-9-el5 yum-22-el5 yum-security-16-el5 yum-rhn-plugin-4-el5 2.修改源配置文件 #vim /etc/yum.repos.d/CentOS-Base.repo (如果目录下没有.repo

Linux下php安装imagick教程详解

说明: php安装目录:/usr/local/php5 php.ini配置文件路径:/usr/local/php5/etc/php.ini Nginx安装目录:/usr/local/nginx Nginx网站根目录:/usr/local/nginx/html 1.安装编译工具 yum install wget make gcc gcc-c++ gtk+-devel zlib-devel openssl openssl-devel pcre-devel kernel keyutils patch

Linux下shell中case命令详解

  linux下shell中的case名字和C/C++中的switch类似,但是shell中的case更强大和复杂. 1.强大主要体现在:shell中case中的关键字可以是字符串类型,而每一项中可以包含正则表达式. 2.复杂主要体现在:shell中case的每一个项后有三个选择:break(常规的break).unconditional follow up(无条件继续)和conditional follow up(有条件继续). 这篇文章的重点是上面的第2点. case的无条件继续和有条件继续

Linux下视频流媒体直播服务器搭建详解

目标: 搭建网络直播流媒体服务器系统(Linux操作系统)   背景: 用于OTT-TV大并发的直播和点播的一套流媒体服务器系统.支持N x 24小时录制回看和直播的服务器端解决方案.   解决方案: l  微软的Windows Media Services l  服务端软件:Windows Media Server l  平台:Windows l  文件格式:ASF, WMV -----------------------------------------------------------

Linux下nl命令的用法详解

Linux中nl命令和cat命令很像,不过nl命令会打上行号,属于比较不常用的命令,下面随小编一起来了解下这个鲜为人知的nl命令吧. nl命令在linux系统中用来计算文件中行号.nl 可以将输出的文件内容自动的加上行号!其默认的结果与 cat -n 有点不太一样, nl 可以将行号做比较多的显示设计,包括位数与是否自动补齐 0 等等的功能. 1.命令格式: nl [选项]... [文件]... 2.命令参数: -b :指定行号指定的方式,主要有两种: -b a :表示不论是否为空行,也同样列出

Linux下C编程:getch()详解

getch() 所在头文件:conio.h 函数用途:从控制台读取一个字符 函数原型:int getch(void) 返回值:读取的字符 例如: char ch;或int ch: getch();或ch=getch(); 用getch();会等待你按下任意键,再继续执行下面的语句: 用ch=getch();会等待你按下任意键之后,把该键字符所对应的ASCII码赋给ch,再执行下面的语句. 易错点: 1.所在头文件是conio.h.而不是stdio.h. 2.在使用之前要调用initscr(),结