如何通过 C 在用户定义的结构中编写双数组并使用 CTYPE 传递给 Python
how to write double array in a user-defined structure by c and pass to python with ctype
我的目标是对结构成员进行C写入,并将结构指针传递回python。 该结构由 2 个相同大小的双精度数组(代表实部和 imag 部分数据,( # 数组中的行,# 的列。 由于它在 Python 中是行主,我可以按类型传递 2d 数组 指针(double(,并且给定 row&col,我可以访问正确的位置。(而不是指针(指针(c_double(((
在蟒蛇中
class tx_data(Structure):
_fields_=[("I", POINTER(c_double)), ("m", c_int), ("n", c_int), ("Q", POINTER(c_double))]
# argtypes& restype for preventing invalid data
writereturn = lib.WriteReturn
writei= lib.WriteI
writereturn.argtypes = [c_int,c_int]
writereturn.restype=POINTER(tx_data)
writei.argtypes = [c_int,c_int,POINTER(tx_data)]
writei.restype= None
函数 WriteI 传递具有零填充数据的结构实例,我希望数组由 C 填充数据。但是,数据没有改变。我不确定是否无法传递结构指针,并且结构还包含指向双精度的指针
def WriteI(Nrow, len):
txData_pointer = POINTER(tx_data)
rec_data = tx_data()
I = np.zeros((Nrow,len), dtype=np.double)
Q = np.zeros((Nrow,len), dtype=np.double)
rec_data.I = I.ctypes.data_as(POINTER(c_double))
rec_data.Q = Q.ctypes.data_as(POINTER(c_double))
rec_data.m = c_int(Nrow)
rec_data.n = c_int(len)
print(addressof(rec_data))
print(txData_pointer.from_address(addressof(rec_data)))
print("in PY--m:%d, n:%d"%(Nrow,len))
writei(Nrow, len, txData_pointer.from_address(addressof(rec_data)))
#rx(Nrow, len, byref(rec_data))
return rec_data
然后我看到了其他帖子,通过指针(结构(返回写入数据。我尝试如下,但弹出OSError:异常:访问违规写入0x0000000000000000
def WriteReturn(Nrow, len):
rec_data = tx_data.from_address(writereturn(Nrow, len))
xk = tx_data()
xk.I = cast(rec_data.contents.I, POINTER(c_double))
xk.Q = cast(rec_data.contents.Q, POINTER(c_double))
xk.m = c_int(Nrow)
xk.n = c_int(len)
return xk
在标题中
typedef struct{
double *I;
int m;
int n;
double *Q;
}tx_data;
extern "C" __declspec(dllexport) void WriteI(int Nrow, int len, tx_data &xk);
extern "C" __declspec(dllexport) tx_data* WriteReturn(int Nrow, int len);
在C++
void WriteI(int Nrow, int len, tx_data &xk) {
size_t t;
for (int i = 0; i < Nrow; i++) {
for (int j = 0; j < len; j++) {
t = len * i + j;
xk.I[t] = 0.3+t;
xk.Q[t] = 0.7+t;
}
}
}
tx_data* WriteReturn(int Nrow, int len) {
tx_data* xk = new tx_data();
size_t t;
xk->m = Nrow;
xk->n = len;
for (int i = 0; i < Nrow; i++) {
for (int j = 0; j < len; j++) {
t = len * i + j;
xk->I[t] = 0.3 + t;
xk->Q[t] = 0.7 + t;
}
}
return xk;
}
谁能阐明如何解决它?
这里有很多问题。
首先,txData_pointer.from_address(addressof(rec_data))
错了。这基本上是*(tx_data **)&rec_data
的 C 等价物,这显然是错误的,因为rec_data
不是指针。如果你想无缘无故地复杂,那就做tx_data.from_address(addressof(rec_data))
,但如果你想简单,那就做byref(rec_data)
。
在那之后,tx_data.from_address(writereturn(Nrow, len))
错了。这里没有必要涉及from_address
;只需保存writereturn
的结果即可。
接下来,void WriteI(int Nrow, int len, tx_data &xk)
错了。不能在声明extern "C"
的函数签名中使用&
。使用*
而不是&
,并将WriteI
更改为使用xk->
而不是xk.
。
最后,在WriteReturn
中,您正在创建一个新的tx_data
,但不会为其分配I
或Q
,尽管尝试写入它们。你需要做xk->I = new double[Nrow * len];
,Q
也是如此。
修复所有这些后,您的代码就可以工作了。这是修复程序(您在 Python 中的class
按原样很好,所以我没有重新发布它(:
def WriteI(Nrow, len):
rec_data = tx_data()
I = np.zeros((Nrow,len), dtype=np.double)
Q = np.zeros((Nrow,len), dtype=np.double)
rec_data.I = I.ctypes.data_as(POINTER(c_double))
rec_data.Q = Q.ctypes.data_as(POINTER(c_double))
rec_data.m = c_int(Nrow)
rec_data.n = c_int(len)
print(addressof(rec_data))
print("in PY--m:%d, n:%d"%(Nrow,len))
writei(Nrow, len, byref(rec_data))
#rx(Nrow, len, byref(rec_data))
return rec_data
def WriteReturn(Nrow, len):
rec_data = writereturn(Nrow, len)
xk = tx_data()
xk.I = cast(rec_data.contents.I, POINTER(c_double))
xk.Q = cast(rec_data.contents.Q, POINTER(c_double))
xk.m = c_int(Nrow)
xk.n = c_int(len)
return xk
typedef struct{
double *I;
int m;
int n;
double *Q;
}tx_data;
extern "C" __declspec(dllexport) void WriteI(int Nrow, int len, tx_data *xk);
extern "C" __declspec(dllexport) tx_data* WriteReturn(int Nrow, int len);
void WriteI(int Nrow, int len, tx_data *xk) {
size_t t;
for (int i = 0; i < Nrow; i++) {
for (int j = 0; j < len; j++) {
t = len * i + j;
xk->I[t] = 0.3+t;
xk->Q[t] = 0.7+t;
}
}
}
tx_data* WriteReturn(int Nrow, int len) {
tx_data* xk = new tx_data();
size_t t;
xk->I = new double[Nrow * len];
xk->m = Nrow;
xk->n = len;
xk->Q = new double[Nrow * len];
for (int i = 0; i < Nrow; i++) {
for (int j = 0; j < len; j++) {
t = len * i + j;
xk->I[t] = 0.3 + t;
xk->Q[t] = 0.7 + t;
}
}
return xk;
}
顺便说一下,你可以做很多事情来改进这段代码,我没有介绍。这只是使其工作所需的最低限度的更改。
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '