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接口了。


目录
相关文章
|
1月前
|
网络协议 安全 Linux
Linux C/C++之IO多路复用(select)
这篇文章主要介绍了TCP的三次握手和四次挥手过程,TCP与UDP的区别,以及如何使用select函数实现IO多路复用,包括服务器监听多个客户端连接和简单聊天室场景的应用示例。
91 0
|
1月前
|
存储 Linux C语言
Linux C/C++之IO多路复用(aio)
这篇文章介绍了Linux中IO多路复用技术epoll和异步IO技术aio的区别、执行过程、编程模型以及具体的编程实现方式。
86 1
Linux C/C++之IO多路复用(aio)
|
1月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
297 3
|
1月前
|
资源调度 Linux 调度
Linux C/C++之线程基础
这篇文章详细介绍了Linux下C/C++线程的基本概念、创建和管理线程的方法,以及线程同步的各种机制,并通过实例代码展示了线程同步技术的应用。
29 0
Linux C/C++之线程基础
|
1月前
|
Linux C++
Linux C/C++之IO多路复用(poll,epoll)
这篇文章详细介绍了Linux下C/C++编程中IO多路复用的两种机制:poll和epoll,包括它们的比较、编程模型、函数原型以及如何使用这些机制实现服务器端和客户端之间的多个连接。
24 0
Linux C/C++之IO多路复用(poll,epoll)
|
1月前
|
网络协议 Linux 网络性能优化
Linux C/C++之TCP / UDP通信
这篇文章详细介绍了Linux下C/C++语言实现TCP和UDP通信的方法,包括网络基础、通信模型、编程示例以及TCP和UDP的优缺点比较。
37 0
Linux C/C++之TCP / UDP通信
|
1月前
|
消息中间件 Linux API
Linux c/c++之IPC进程间通信
这篇文章详细介绍了Linux下C/C++进程间通信(IPC)的三种主要技术:共享内存、消息队列和信号量,包括它们的编程模型、API函数原型、优势与缺点,并通过示例代码展示了它们的创建、使用和管理方法。
32 0
Linux c/c++之IPC进程间通信
|
1月前
|
Linux C++
Linux c/c++进程间通信(1)
这篇文章介绍了Linux下C/C++进程间通信的几种方式,包括普通文件、文件映射虚拟内存、管道通信(FIFO),并提供了示例代码和标准输入输出设备的应用。
28 0
Linux c/c++进程间通信(1)
|
1月前
|
Linux C++
Linux c/c++之进程的创建
这篇文章介绍了在Linux环境下使用C/C++创建进程的三种方式:system函数、fork函数以及exec族函数,并展示了它们的代码示例和运行结果。
37 0
Linux c/c++之进程的创建
|
1月前
|
Linux C++
Linux c/c++进程之僵尸进程和守护进程
这篇文章介绍了Linux系统中僵尸进程和守护进程的概念、产生原因、解决方法以及如何创建守护进程。
21 0