在C代码调用C++代码
由于历史原因,以及不同开发人员的技术偏好,C语言和C++语言都有一些独有的非常有价值的项目,因而两种语言的互操作,充分利用前人造的轮子是一件非常有价值的事情。
C++代码调用C代码很简单,只要分别在包含的C头文件的开头和结尾加上如下的两个块:
|
|
和
|
|
即可。
然而为了支持类、重载等更加高级的特性,在编译C++代码时,C++符号会被修饰。我们dump Linux平台加密库 libcrypto++ 的符号表,可以看到如下的内容:
|
|
这与我们在源文件和头文件里看到的那些函数、类的声明定义都不一样。通过binutils的工具c++filt demangle这些符号可以让我们看到它们在代码里的样子:
|
|
那到底有没有办法在C代码中调用C++代码呢?方法当然是有的,而且还不止一种。
在 .cpp 文件中定义一个函数,声明为extern "C",则该函数可以方便地在C代码中调用。由于该函数在 .cpp 文件中定义,因而在该函数的实现中,可以调用任意的C++代码,包括C++函数,创建C++类等等。
C++头文件:
|
|
C++实现文件如下:
|
|
在C代码里调用C++函数:
|
|
在C++文件里定义的c_func函数就像一座桥一样,连接了C代码的世界和C++代码的世界。但 C 函数c_func的参数及返回值的类型自然是受到一定的限制的,但在函数实现中可以适配要调用的C++接口,做一些适配。
通过dlopen/dlsym调用
借助于在 .cpp 文件中定义的C函数,间接地调用C++接口,固然是能实现在 C 代码中调用C++代码的目标,然而还是有些麻烦。通过libdl提供的接口,可以使我们的目标通过更简便的方式实现。
为dlsym传入经过修饰的符号,可以找到对应的函数的地址。
通过如下命令将上面的CPPFunctions.cpp文件编译为一个动态链接库:
|
|
通过dlopen和dlsym找到对应的C++函数,并将其强制类型转换为适当类型的函数指针,然后通过函数指针调用目标函数,如:
|
|
编译并执行上面的代码,在我的机器上可以看到如下的输出:
|
|
参考资料
C++-dlopen-mini-HOWTO
Using dlsym in c++ without extern “C”
关于linker的笔记
在C代码调用C++代码的更多相关文章
- C代码调用Java代码
C代码调用Java代码应用场景 复用已经存在的java代码 c语言需要给java一些通知 c代码不方便实现的逻辑(界面) 反射 //1.加载类字节码 Class clazz = Demo.class. ...
- 02_JNI中Java代码调用C代码,Android中使用log库打印日志,javah命令的使用,Android.mk文件的编写,交叉编译
1 编写以下案例(下面的三个按钮都调用了底层的C语言): 项目案例的代码结构如下: 2 编写DataProvider的代码: package com.example.ndkpassdata; ...
- Linux下C/C++代码调用PHP代码(转)
Linux下C/C++代码可以通过popen系统函数调用PHP代码并通过fgets函数获取PHP代码echo输出的字符串. //main.c char str[1024] = {0}; char * ...
- UpdatePanel中用后台CS代码调用JS代码,先执行控件事件,后触发JS
引用地址: http://www.cnblogs.com/silenkee/articles/1609831.html 页面中加入了UpdatePanel后,Response.Write(&quo ...
- jni中c代码调用java代码
原理是使用反射的机制 java中反射的例子: Class<?> forName = Class.forName("com.example.ndkcallback.DataProv ...
- 01_JNI是什么,为什么使用,怎么用JNI,Cygwin环境变量配置,NDK案例(使用Java调用C代码),javah命令使用
1 什么是JNI JNI Java本地开发接口 JNI是一个协议,这个协议用来沟通java代码和外部的本地代码(C/C++) 通过这个协议,java代码就可以调用外部的C/C++代码,外部的C/C++ ...
- 如何实现 javascript “同步”调用 app 代码
在 App 混合开发中,app 层向 js 层提供接口有两种方式,一种是同步接口,一种一异步接口(不清楚什么是同步的请看这里的讨论).为了保证 web 流畅,大部分时候,我们应该使用异步接口,但是某些 ...
- 1.JAVA中使用JNI调用C++代码学习笔记
Java 之JNI编程1.什么是JNI? JNI:(Java Natibe Inetrface)缩写. 2.为什么要学习JNI? Java 是跨平台的语言,但是在有些时候仍然是有需要调用本地代码 ( ...
- ngui中 代码调用按钮事件(后来改成了按钮绑定键盘..)
ngui中 代码调用按钮事件 好烦人啊这个问题, 我弄完发上来 这个问题解决了一半 发现可以用 按钮绑定来解决这个问题,并且更安全方便快速 直接在按钮上添加一个 key binding 指定按键 搞定 ...
随机推荐
- ant design for vue 刷新页面,根据当前路由选中相应菜单
<a-menu theme="dark" mode="horizontal" class="menu__a" @select=&quo ...
- 二分查找(python)
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2018/4/29 9:11 # @Author : Jackendoff # @Sit ...
- c++17 optional 简介
c++17 的optional 作为返回值,提高异常的处理 对于构造可能失败的对象,似乎在构造函数里抛异常不太合适.所以 首先是使用静态方法来返回对象,在外部申请资源后,再通过传参给构造函数. 这样的 ...
- Opencv笔记(一):图像的基本操作
1.图像的读.显示和保存操作 import cv2 img = cv2.imread('filename',0); cv2.imshow('name',img); k=cv2.waitKey(0); ...
- Perl:理解正则中“.”可匹配出回车符(“\n”)外任意字符的例子,配合 $^I 关键字
要把下面文件的内容改了, Program name: graniteAuthor: Gilbert BatesCompany: RockSoftDepartment: R&DPhone: +1 ...
- Convert between Unix and Windows text files - IU Knowledge Base from: https://kb.iu.edu/d/acux
vi. To input the ^M character, press Ctrl-v , and then press Enter or return . In vim, use :set ff=u ...
- TOJ-3474 The Big Dance(递归二分)
链接:https://ac.nowcoder.com/acm/contest/1077/L 题目描述 Bessie and the herd, N (1 <= N <= 2,200) co ...
- [LC] 146. LRU Cache
Design and implement a data structure for Least Recently Used (LRU) cache. It should support the fol ...
- 00 - 准备 Anaconda 环境
Anaconda 环境 官方下载安装包:https://www.anaconda.com/download/ Anaconda Navigtor :用于管理工具包和环境的图形用户界面,后续涉及的众多管 ...
- Django线上部署实战教程之Nginx+Gunicorn+Django篇
############################################# 推荐 nginx supervisor gunicorn 配置简单,运维方便. Nginx (engi ...