python - 使用 ctypes 创建用于包装结构的数据类型
问题描述
所以我正在学习ctypes
,我有类似以下的情况:
我有一个共享库,其中包含实现双精度矩阵和复数矩阵的结构。我想用ctypes
. 我知道我可以创建两个类来包装每个结构,但我想知道是否有一种直接的方法可以通过指定数据类型将两个结构与一个类一起包装。
例如,也许我的库libmatrix.so
有以下源文件:
// matrix.c
struct complex {
double re;
double im;
};
struct Matrix {
int nrow;
int ncol;
double *data
};
struct CMatrix {
int nrow;
int ncol;
complex *data
};
typedef struct complex complex;
typedef struct Matrix Matrix;
typedef struct CMatrix CMatrix;
包装我的complex
结构后,可能是这样的:
class complex(Structure):
__fields__ = [("re", c_double), ("im", c_double)]
在 python 中,我想创建一个Matrix
让我执行以下操作的类:
# create 2 x 3 matrix of doubles
m = Matrix(2, 3, dtype=c_double)
# create 2 x 3 matrix of complex numbers (structure that I made)
n = Matrix(2, 3, dtype=complex)
我知道 numpy 有这样的东西,我尝试查阅源代码,但我不知所措。这种类型的东西有名称或有参考吗?任何方向将不胜感激。
解决方案
这是一个粗略的例子,它是如何完成的。Python 中的一切都是对象,因此可以直接传递数据类型并用于分配数组。一些覆盖使矩阵更易于操作和显示。
from ctypes import *
from pprint import pformat
class Complex(Structure):
_fields_ = (('re',c_double),
('im',c_double))
def __repr__(self):
return f'Complex({self.re}{self.im:+}j)'
def __str__(self):
return f'{self.re}{self.im:+}j'
class Matrix(Structure):
_fields_ = (('nrow',c_int),
('ncol',c_int),
('data',c_void_p))
def __init__(self,row,col,dtype):
self.nrow = row
self.ncol = col
self._data = (dtype * col * row)() # internal instance of allocated array
self.data = cast(byref(self._data),c_void_p) # generic pointer to array
# forward to the array instance
def __getitem__(self,key):
return self._data.__getitem__(key)
# forward to the array instance
def __setitem__(self,key,value):
return self._data.__setitem__(key,value)
def __repr__(self):
return pformat([r[:] for r in self._data])
mc = Matrix(2,3,Complex)
md = Matrix(3,2,c_double)
mc[1][2] = Complex(1.1,-2.2)
md[2][1] = 1.5
print(mc)
print(md)
输出:
[[Complex(0.0+0.0j), Complex(0.0+0.0j), Complex(0.0+0.0j)],
[Complex(0.0+0.0j), Complex(0.0+0.0j), Complex(1.1-2.2j)]]
[[0.0, 0.0], [0.0, 0.0], [0.0, 1.5]]
推荐阅读
- image-processing - 八度windows7无法安装图像采集包
- applescript - AppleScript 将文件移动到正确的位置
- linux - 无法在 Ubuntu Server 18.04 上找到包 phpmyadmin
- php - 资产未在 codeIgniter 中加载
- objective-c - 如何改进我的代码(C/Objective C)乒乓球比赛
- javascript - 如何使用来自 mobx 商店的数据填充 div?
- google-api - 使用 Postman 的服务帐户对 Google Cloud Storage JSON API 进行身份验证
- php - PHP; 如何将受密码保护的登录信息安全地存储为 cookie?
- amazon-web-services - 如何使 AWS ECS 任务定义使 EC2 实例可公开访问?
- reactjs - react.js - 使用自定义路径运行 npm run build