详解python如何调用C/C++底层库与互相传值


Posted in Python onAugust 10, 2016

前言

开发环境:

Centos 7 + Python 3.5.1 + Qt Creator(只是使用Qt Creator编译而已,并没有使用QT的任何库)

Python调用C/C++库,我现在能做到的有两种方式

1.extern “C” 导出(互相传值比较麻烦,不建议使用这种方式):

将C/C++库做成和平常一样的DLL和或者.so,比如:

//.h文件
#include <Python.h>
//.cpp文件
//C/C++ my.so 或者my.dll
enter "C" void printHello()
{
  std::cout<<"Hello World"<<std::endl;
}
#Python
import ctypes 
from ctypes import *
loadso = ctypes.cdll.LoadLibrary 
mylib = loadso("./my.so")
mylib.printHello()
>>>Hello world

代码解释:

my.so 有一个C导出函数 printHello()

import ctypes  : 导入官方的一个库,顾名思义和C有关

loadso = ctypes.cdll.LoadLibrary  : loadso 表示加载库用的函数

mylib = loadso(“./my.so”)  //或者loadso(“my.dll”)  加载my.so库

mylib.printHello() : 调用库函数

上述代码能正常输出:Hello World,但是他们没有互相传值

Python和C++互相传值

//.h文件
#include <Python.h>
//.cpp文件
enter "C" int printHello(const char* str)
{
  std::cout<<str<<std::endl;
  return 1;  
}

那么Python的问题就来了

str = create_string_buffer(b"Hello World")
#mylib.printHello("Hello World") 这里死活就是显示:H,*(str+4)才是'e',*(str+8) 是'l' 依次类推
print (mylib.printHello(str))
>>>Hello World
>>>1
#由于对Python不是特别的熟悉 怎么也做不到显示C++返回的字符串, Python只能显示C++返回的字符串子能看到一个地址而已

2.Python扩展C/C++

不多说,直接上代码

//.h文件 本来这是C++连接Mysql 我只摘抄部分代#include <Python.h>
//.cpp文件
//传递多个参数 Python传过来的参数在args里面
PyObject* printfHello(PyObject* self,PyObject* args)
{
  int i=0
   const char* str;
  if (!PyArg_ParseTuple(args, "i|s", &i,&str))   //i 表示整形 s 表示字符串
    return PyLong_FromLong(0);
  print("%d,%s",i,str);
  return Py_BuildValue("s","OK");  //向Python返回OK字符串
}
//映射 知道MFC的一看就懂
static PyMethodDef MyMethods[] = {
{"printfHello", printfHello, METH_VARARGS,  //"printHello" 中可调用的函数 METH_VARARGS :带有参数   METH_NOARGS:无参数
"print"},   //说明
{"connect", connect, METH_VARARGS,
"connect mysql"},
{NULL, NULL, 0, NULL}
};
static PyObject* UtilError;
// 向Python中注册模块
static struct PyModuleDef spammodule = { 
PyModuleDef_HEAD_INIT,
"libMysqlUtil", //模块名字 import libMysqlUtil
"C++ Connect Mysql",
-1,
MyMethods
};//PyInit_libMysqlUtil 注意名字 一定要PyInit_ 加上你的模块名字 不然Python import 会提示没有定义 PyInit_你的模块名字 PyMODINIT_FUNC PyInit_libMysqlUtil(void) { PyObject* m = nullptr; m = PyModule_Create(&spammodule);
//m= Py_InitModule(....) Python 2.7 if(!m) { return m; } UtilError = PyErr_NewException("Util.error",NULL,NULL); Py_INCREF(UtilError); PyModule_AddObject(m,"error",UtilError); return m; }
#python
import libMysqlUtil
libMysqlUtil.printHello(1,"hello World")
>>>1,hello World
>>>OK

总结

到目前为止Python和C/C++互相通信,能适应大部分需求,结构体传值还没有研究,对于类,使用指针就行,C++里面是指针,在Python中会将指针转化成整形,Python将这个整形传给C++的时候使用PyArg_ParseTuple又将整形会变成类指针。

好了,以上就是本文的全部内容,希望本文的内容对大家学习python和C/C++能有所帮助。

Python 相关文章推荐
在Gnumeric下使用Python脚本操作表格的教程
Apr 14 Python
python中__call__内置函数用法实例
Jun 04 Python
一个基于flask的web应用诞生(1)
Apr 11 Python
Python批量提取PDF文件中文本的脚本
Mar 14 Python
浅谈python numpy中nonzero()的用法
Apr 02 Python
详解分布式任务队列Celery使用说明
Nov 29 Python
Python微医挂号网医生数据抓取
Jan 24 Python
解决Mac下使用python的坑
Aug 13 Python
python实现对列表中的元素进行倒序打印
Nov 23 Python
Python通过len函数返回对象长度
Oct 22 Python
python3 通过 pybind11 使用Eigen加速代码的步骤详解
Dec 07 Python
python文本处理的方案(结巴分词并去除符号)
May 26 Python
浅析python中的分片与截断序列
Aug 09 #Python
总结python爬虫抓站的实用技巧
Aug 09 #Python
教你用Type Hint提高Python程序开发效率
Aug 08 #Python
Python如何实现文本转语音
Aug 08 #Python
Python脚本处理空格的方法
Aug 08 #Python
基于Python实现对PDF文件的OCR识别
Aug 05 #Python
利用Python实现命令行版的火车票查看器
Aug 05 #Python
You might like
PHP中的traits简单使用实例
2015/05/13 PHP
php实现三级级联下拉框
2016/04/17 PHP
PHP SFTP实现上传下载功能
2017/07/26 PHP
详解php用static方法的原因
2018/09/12 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
增强的 JavaScript 的 trim 函数的代码
2007/08/13 Javascript
类似CSDN图片切换效果脚本
2009/09/17 Javascript
jQuery源码分析之Event事件分析
2010/06/07 Javascript
AlertBox 弹出层信息提示框效果实现步骤
2010/10/11 Javascript
js单独获取一个checkbox看其是否被选中
2014/09/22 Javascript
js仿支付宝填写支付密码效果实现多方框输入密码
2016/03/09 Javascript
jQuery animate easing使用方法图文详解
2016/06/17 Javascript
AngularJS入门教程之模块化操作用法示例
2016/11/02 Javascript
jQuery动态增减行的实例代码解析(推荐)
2016/12/05 Javascript
原生js实现简单的链式操作
2017/07/04 Javascript
Vue AST源码解析第一篇
2017/07/19 Javascript
AngularJS实现的select二级联动下拉菜单功能示例
2017/10/25 Javascript
jquery实现回车键触发事件(实例讲解)
2017/11/21 jQuery
nodeJs实现基于连接池连接mysql的方法示例
2018/02/10 NodeJs
基于js中的存储键值对以及注意事项介绍
2018/03/30 Javascript
Electron 调用命令行(cmd)
2019/09/23 Javascript
详解Django中的ifequal和ifnotequal标签使用
2015/07/16 Python
通过数据库向Django模型添加字段的示例
2015/07/21 Python
numpy.linspace函数具体使用详解
2019/05/27 Python
python单向链表的基本实现与使用方法【定义、遍历、添加、删除、查找等】
2019/10/24 Python
window7下的python2.7版本和python3.5版本的opencv-python安装过程
2019/10/24 Python
Python如何使用bokeh包和geojson数据绘制地图
2020/03/21 Python
基于python实现FTP文件上传与下载操作(ftp&amp;sftp协议)
2020/04/01 Python
详解python实现可视化的MD5、sha256哈希加密小工具
2020/09/14 Python
基于CSS3实现的黑色个性导航菜单效果
2015/09/14 HTML / CSS
购买澳大利亚最好的服装和内衣在线:BONDS
2016/10/14 全球购物
爱游人:Travelliker
2017/09/05 全球购物
J2SDK1.5与J2SDK5.0有什么区别
2012/09/19 面试题
三年级音乐教学反思
2014/01/28 职场文书
师范毕业生求职信
2014/07/11 职场文书
2014年计生工作总结
2014/11/21 职场文书