python调用c++ ctype list传数组或者返回数组的方法


Posted in Python onFebruary 13, 2019

示例1:

pycallclass.cpp:

#include <iostream>
using namespace std;
typedef unsigned char BYTE;
#define MAX_COUNT 20
 
struct tagOutCardResult_py
{
	BYTE							cbCardCount;					
	BYTE							cbResultCard1;
	BYTE							cbResultCard2;
	BYTE							cbResultCard3;
	BYTE							cbResultCard4;
	BYTE							cbResultCard5;
	BYTE							cbResultCard6;
	BYTE							cbResultCard7;
	BYTE							cbResultCard8;
	BYTE							cbResultCard9;
	BYTE							cbResultCard10;
	BYTE							cbResultCard11;
	BYTE							cbResultCard12;
	BYTE							cbResultCard13;
	BYTE							cbResultCard14;
	BYTE							cbResultCard15;
	BYTE							cbResultCard16;
	BYTE							cbResultCard17;
	BYTE							cbResultCard18;
	BYTE							cbResultCard19;
	BYTE							cbResultCard20;
};
 
struct tagOutCardResult
{
	BYTE							cbCardCount;					
	BYTE							cbResultCard[MAX_COUNT];		
	void clear()
	{
		cbCardCount = 0;
		for (int nIdx = 0;nIdx < MAX_COUNT;++nIdx)
		{
			cbResultCard[nIdx] = 0;
		}
	}	
	void topy(tagOutCardResult_py* ppy)
	{
		cout<<"topy function begin"<<endl;
		ppy->cbCardCount = cbCardCount;
		cout<<"topy function 1"<<endl;
		ppy->cbResultCard1 = cbResultCard[1 - 1];
		cout<<"topy function 2"<<endl;
		ppy->cbResultCard2 = cbResultCard[2 - 1];
		ppy->cbResultCard3 = cbResultCard[3 - 1];
		ppy->cbResultCard4 = cbResultCard[4 - 1];
		ppy->cbResultCard5 = cbResultCard[5 - 1];
		ppy->cbResultCard6 = cbResultCard[6 - 1];
		ppy->cbResultCard7 = cbResultCard[7 - 1];
		ppy->cbResultCard8 = cbResultCard[8 - 1];
		ppy->cbResultCard9 = cbResultCard[9 - 1];
		ppy->cbResultCard10 = cbResultCard[10 - 1];
		ppy->cbResultCard11 = cbResultCard[11 - 1];
		ppy->cbResultCard12 = cbResultCard[12 - 1];
		ppy->cbResultCard13 = cbResultCard[13 - 1];
		ppy->cbResultCard14 = cbResultCard[14 - 1];
		ppy->cbResultCard15 = cbResultCard[15 - 1];
		ppy->cbResultCard16 = cbResultCard[16 - 1];
		ppy->cbResultCard17 = cbResultCard[17 - 1];
		ppy->cbResultCard18 = cbResultCard[18 - 1];
		ppy->cbResultCard19 = cbResultCard[19 - 1];
		ppy->cbResultCard20 = cbResultCard[20 - 1];
		cout<<"topy function end"<<endl;
	}
};
 
class TestLib
{
	public:
		void display(tagOutCardResult& ret);
};
void TestLib::display(tagOutCardResult& ret) {
	ret.cbCardCount = 3;
	ret.cbResultCard[0] = 1;
	ret.cbResultCard[1] = 50;
	ret.cbResultCard[2] = 100;
 
	cout<<"First display aaa ";
	cout<<"hello ";
	cout<<"world ";
}
 
extern "C" {
	TestLib oGameLogic;
	void display(tagOutCardResult_py* ret_py) {
		tagOutCardResult oRet;
		oGameLogic.display(oRet);
		cout<<"before topy"<<endl;
		oRet.topy(ret_py);
		cout<<"after topy"<<endl;
		cout<<"in cpp:ret_py->cbCardCount:"<<ret_py->cbCardCount<<endl;
		cout<<"in cpp:ret_py->cbResultCard1:"<<ret_py->cbResultCard1<<endl;
		cout<<" this:" << ret_py << endl;
	}
}

编译脚本:

g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp -I/usr/include/python2.6 -L/usr/lib64/python2.6/config

Game.py调用部分。类声明:

import ctypes
 
class tagOutCardResult_py(ctypes.Structure):
 _fields_ = [("cbCardCount", ctypes.c_ubyte), \
("cbResultCard1", ctypes.c_ubyte), \
("cbResultCard2", ctypes.c_ubyte), \
("cbResultCard3", ctypes.c_ubyte), \
("cbResultCard4", ctypes.c_ubyte), \
("cbResultCard5", ctypes.c_ubyte), \
("cbResultCard6", ctypes.c_ubyte), \
("cbResultCard7", ctypes.c_ubyte), \
("cbResultCard8", ctypes.c_ubyte), \
("cbResultCard9", ctypes.c_ubyte), \
("cbResultCard10", ctypes.c_ubyte), \
("cbResultCard11", ctypes.c_ubyte), \
("cbResultCard12", ctypes.c_ubyte), \
("cbResultCard13", ctypes.c_ubyte), \
("cbResultCard14", ctypes.c_ubyte), \
("cbResultCard15", ctypes.c_ubyte), \
("cbResultCard16", ctypes.c_ubyte), \
("cbResultCard17", ctypes.c_ubyte), \
("cbResultCard18", ctypes.c_ubyte), \
("cbResultCard19", ctypes.c_ubyte), \
("cbResultCard20", ctypes.c_ubyte)]

Game.py调用部分。具体调用:

import ctypes
  so = ctypes.cdll.LoadLibrary
  lib = so("./libpycallclass.so")
  ERROR_MSG('display(\)')
  ret = tagOutCardResult_py(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
  ERROR_MSG("before lib.display(ctypes.byref(ret))")
  lib.display(ctypes.byref(ret))
  ERROR_MSG("after lib.display(ctypes.byref(ret))")
  ERROR_MSG('#######################################################################################')
  ERROR_MSG(ret)
  ERROR_MSG(ret.cbCardCount)
  ERROR_MSG(ret.cbResultCard1)
  ERROR_MSG(ret.cbResultCard2)
  ERROR_MSG(ret.cbResultCard3)
  ERROR_MSG(type(ret))

传入一个结构体,使用引用返回,回到python中打印出来结果是对的。

这样就可以传入,可以传出了。

示例1end#########################################################################

示例2:

pycallclass.cpp:

#include <iostream>
using namespace std;
typedef unsigned char BYTE;
#define MAX_COUNT 20
 
#if defined(WIN32)||defined(WINDOWS)
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT
#endif
 
struct ByteArray_20
{
	BYTE e1;
	BYTE e2;
	BYTE e3;
	BYTE e4;
	BYTE e5;
	BYTE e6;
	BYTE e7;
	BYTE e8;
	BYTE e9;
	BYTE e10;
	BYTE e11;
	BYTE e12;
	BYTE e13;
	BYTE e14;
	BYTE e15;
	BYTE e16;
	BYTE e17;
	BYTE e18;
	BYTE e19;
	BYTE e20;
};
struct ByteArray_20_3
{
	ByteArray_20 e1;
	ByteArray_20 e2;
	ByteArray_20 e3;
};
 
struct ByteArrayNew_20_3
{
	BYTE e[3][20];
};
 
class TestLib
{
	public:
		void LogicFunc(ByteArray_20_3& ret);
		void LogicFuncNew(ByteArrayNew_20_3& ret);
};
void TestLib::LogicFunc(ByteArray_20_3& ret) {
	ret.e1.e1 = 3;
	ret.e1.e2 = 1;
	ret.e1.e3 = 50;
	ret.e2.e1 = 100;
	ret.e2.e2 = 200;
	ret.e2.e3 = 20;
 
	cout<<"TestLib::LogicFunc"<<endl;
}
void TestLib::LogicFuncNew(ByteArrayNew_20_3& ret) {
	ret.e[0][0] = 31;
	ret.e[0][1] = 11;
	ret.e[0][2] = 51;
	ret.e[1][0] = 101;
	ret.e[1][1] = 201;
	ret.e[1][2] = 21;
 
	cout << "TestLib::LogicFuncNew" << endl;
}
 
extern "C" {
	TestLib oGameLogic;
	void DLL_EXPORT display(ByteArray_20_3* pret) {
		cout<<"cpp display func begin"<<endl;
		oGameLogic.LogicFunc(*pret);
		cout<<"cpp display func end"<<endl;
	}
	void DLL_EXPORT display2(ByteArrayNew_20_3* pret) {
		cout << "cpp display2 func begin" << endl;
		oGameLogic.LogicFuncNew(*pret);
		cout << "cpp display2 func end" << endl;
	}
}

pycallclass.py:

import ctypes
 
def ERROR_MSG(str):
 print str
 
class ByteArray_20(ctypes.Structure):
 _fields_ = [\
("e1", ctypes.c_ubyte), \
("e2", ctypes.c_ubyte), \
("e3", ctypes.c_ubyte), \
("e4", ctypes.c_ubyte), \
("e5", ctypes.c_ubyte), \
("e6", ctypes.c_ubyte), \
("e7", ctypes.c_ubyte), \
("e8", ctypes.c_ubyte), \
("e9", ctypes.c_ubyte), \
("e10", ctypes.c_ubyte), \
("e11", ctypes.c_ubyte), \
("e12", ctypes.c_ubyte), \
("e13", ctypes.c_ubyte), \
("e14", ctypes.c_ubyte), \
("e15", ctypes.c_ubyte), \
("e16", ctypes.c_ubyte), \
("e17", ctypes.c_ubyte), \
("e18", ctypes.c_ubyte), \
("e19", ctypes.c_ubyte), \
("e20", ctypes.c_ubyte)]
 
 
class ByteArray_20_3(ctypes.Structure):
 _fields_ = [\
("e1", ByteArray_20), \
("e2", ByteArray_20), \
("e3", ByteArray_20)]
 def __init__(self):
  self.aaa = 123
  self.bbb = [1, 2, 3, 4, 5]
  self.ccc = "alksdfjlasdfjk"
 def test(self):
  self.aaa = 123
  self.bbb = [1, 2, 3, 4, 5]
  self.ccc = "alksdfjlasdfjk"
  self.e1.e1 = 5
  self.e1.e2 = 20
 
 
so = ctypes.cdll.LoadLibrary
lib = so("./libpycallclass.dll")
print('display()')
ret = ByteArray_20_3()
ret.test()
ERROR_MSG(ret.e1.e1)
ERROR_MSG(ret.e1.e2)
print("before lib.display(ctypes.byref(ret))")
lib.display(ctypes.byref(ret))
print("after lib.display(ctypes.byref(ret))")
print('#######################################################################################')
print(ret)
ERROR_MSG(ret.e1)
ERROR_MSG(ret.e2)
ERROR_MSG(ret.e3)
ERROR_MSG(ret.e1.e1)
ERROR_MSG(ret.e1.e2)
ERROR_MSG(ret.e1.e3)
ERROR_MSG(ret.e2.e1)
ERROR_MSG(ret.e2.e2)
ERROR_MSG(ret.e2.e3)
ERROR_MSG(type(ret))
 
print("before lib.display2(ctypes.byref(ret))")
lib.display2(ctypes.byref(ret))
print("after lib.display2(ctypes.byref(ret))")
print('#######################################################################################')
print(ret)
ERROR_MSG(ret.e1)
ERROR_MSG(ret.e2)
ERROR_MSG(ret.e3)
ERROR_MSG(ret.e1.e1)
ERROR_MSG(ret.e1.e2)
ERROR_MSG(ret.e1.e3)
ERROR_MSG(ret.e2.e1)
ERROR_MSG(ret.e2.e2)
ERROR_MSG(ret.e2.e3)
ERROR_MSG(type(ret))
 
ret.test()
ERROR_MSG(ret.e1.e1)
ERROR_MSG(ret.e1.e2)

g++:

g++ -o libpycallclass.so -shared -fPIC pycallclass.cpp -I/usr/include/python2.6 -L/usr/lib64/python2.6/config

windows:

新建一个DLL工程,把pycallclass.cpp加进去,编译成DLL就OK了。

千万注意python的运行时是32位的还是64位的,DLL或者SO必须和它对应。

python类可以嵌套使用,继承ctypes.Structure,部分成员是_fields_里定义的,部分成员在__init__里定义,这样的类也可以ctypes.byref(self)传进c++去,传的是指针,传入传出就都OK了。

注意示例2中ByteArrayNew_20_3的用法,python中是定义了20个变量,c++中是直接一个二维数组。内存结构是一致的,所以可以直接这样使用。注意类型和长度必须一致,否则可能会内存访问越界。

以上这篇python调用c++ ctype list传数组或者返回数组的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
使用Python3中的gettext模块翻译Python源码以支持多语言
Mar 31 Python
使用Python操作MySQL的一些基本方法
Aug 16 Python
python实现mysql的单引号字符串过滤方法
Nov 14 Python
Python 高级专用类方法的实例详解
Sep 11 Python
使用django-crontab实现定时任务的示例
Feb 26 Python
解析Python的缩进规则的使用
Jan 16 Python
Django中使用Whoosh进行全文检索的方法
Mar 31 Python
Python3.5 Pandas模块之DataFrame用法实例分析
Apr 23 Python
解决windows下python3使用multiprocessing.Pool出现的问题
Apr 08 Python
python golang中grpc 使用示例代码详解
Jun 03 Python
Python如何执行精确的浮点数运算
Jul 31 Python
Python开发入门——迭代的基本使用
Sep 03 Python
python调用c++传递数组的实例
Feb 13 #Python
利用ctypes获取numpy数组的指针方法
Feb 12 #Python
python3利用ctypes传入一个字符串类型的列表方法
Feb 12 #Python
使用python绘制二元函数图像的实例
Feb 12 #Python
python matplotlib实现双Y轴的实例
Feb 12 #Python
对Pycharm创建py文件时自定义头部模板的方法详解
Feb 12 #Python
numpy基础教程之np.linalg
Feb 12 #Python
You might like
PHP操作文件方法问答
2007/03/16 PHP
php统计文章排行示例
2014/03/04 PHP
php通过session防url攻击方法
2014/12/10 PHP
详解PHP中的状态模式编程
2015/08/11 PHP
PHP操作路由器实现方法示例
2019/04/27 PHP
解决PHP curl或file_get_contents下载图片损坏或无法打开的问题
2019/10/11 PHP
超级兔子让浮动层消失的前因后果
2007/03/09 Javascript
学习并汇集javascript匿名函数
2010/11/25 Javascript
myeclipse安装jQuery插件的方法
2011/03/29 Javascript
js获取触发事件元素在整个网页中的绝对坐标(示例代码)
2013/12/13 Javascript
JS中递归函数
2016/06/17 Javascript
jquery实现提示语淡入效果
2017/05/05 jQuery
nodejs+mongodb+vue前后台配置ueditor的示例代码
2018/01/02 NodeJs
vue element项目引入icon图标的方法
2018/06/06 Javascript
小程序实现抽奖动画
2020/04/16 Javascript
解决vue单页面 回退页面 keeplive 缓存问题
2020/07/22 Javascript
简单文件操作python 修改文件指定行的方法
2013/05/15 Python
Mac OS X10.9安装的Python2.7升级Python3.3步骤详解
2013/12/04 Python
Python的几个高级语法概念浅析(lambda表达式闭包装饰器)
2016/05/28 Python
Python环境搭建之OpenCV的步骤方法
2017/10/20 Python
python+pillow绘制矩阵盖尔圆简单实例
2018/01/16 Python
python批量复制图片到另一个文件夹
2018/09/17 Python
Python 处理文件的几种方式
2019/08/23 Python
Python常用模块sys,os,time,random功能与用法实例分析
2020/01/07 Python
Pycharm导入anaconda环境的教程图解
2020/07/31 Python
CSS3径向渐变之大鱼吃小鱼之孤单的大鱼
2016/04/26 HTML / CSS
美国名表在线商城:Ashford(支持中文)
2019/09/24 全球购物
常见的软件开发流程有哪些
2015/11/14 面试题
写自荐信的七个技巧
2013/10/15 职场文书
专科应届生求职信
2013/11/24 职场文书
培训班开班主持词
2015/07/02 职场文书
2015年暑假生活总结
2015/07/13 职场文书
企业培训简报范文
2015/07/20 职场文书
导游词之江西赣州
2019/10/15 职场文书
pytorch查看网络参数显存占用量等操作
2021/05/12 Python
制作能在nginx和IIS中使用的ssl证书
2021/06/21 Servers