执行您所说的操作的一种方法是直接在 python 端分配 numpy 数组,并在 C 端表现得像一个直接的双精度数组。
import numpy as np
import ctypes as C
# allocate this as a normal numpy array with specified dtype
array_1d_double = np.array([1,2,3,4,5],dtype="float64")
# set the structure to contain a C double pointer
class Test(C.Structure):
_fields_ = [("x", C.POINTER(C.c_double))]
# Instantiate the structure so it can be passed to the C code
test = Test(np.ctypeslib.as_ctypes(array_1d_double))
# You can also do:
# test = Test()
# test.x = np.ctypeslib.as_ctypes(array_1d_double)
print test.x
# outputs: <__main__.LP_c_double object at 0x1014aa320>
您现在应该能够使用该结构的x
成员作为 C 代码中的普通双精度数组。
EDIT:
澄清一下:如果你实例化一个Structure
没有参数,它提供了NULL
为其所有成员提供指导。
class Test(C.Structure):
_fields_ = [("x", C.POINTER(C.c_double)),
("y", C.POINTER(C.c_int))]
test = Test()
print test.x
# outputs: <__main__.LP_c_double object at 0x1014aa320>
print test.y
# outputs: <__main__.LP_c_int object at 0x101429320>
print test.x[0]
# raises ValueError: NULL pointer access
print test.y[0]
# raises ValueError: NULL pointer access
如果使用 N 个参数实例化结构,这些参数将分配给结构的前 N 个成员。
test = Test(np.ctypeslib.as_ctypes(array_1d_double))
print text.x[0]
# outputs: 1.0
print test.y[0]
# raises ValueError: NULL pointer access
EDIT2
如果您想将 numpy 数组永久绑定到您的结构,您可以覆盖__init__
method:
class MyDualArrayStruct(C.Structure):
_fields_ = [("c_x", C.POINTER(C.c_double)),
("c_y", C.POINTER(C.c_int))]
def __init__(self,*args,**kwargs):
super(MyDualArrayStruct,self).__init__(*args,**kwargs)
self.np_x = np.array([1,2,3,4,5],dtype="float64")
self.c_x = np.ctypeslib.as_ctypes(self.np_x)
self.np_y = np.array([5,4,3,2,1],dtype="int32")
self.c_y = np.ctypeslib.as_ctypes(self.np_y)
test = MyDualArrayStruct()
print test.np_x
print test.c_x[:5]
# Note that here c_x and np_x both contain the same data. Thus modifying one of them
# (inplace) modifies the other. You can use this to do easy inplace modification of
# numpy arrays in C functions.
# This implies that test.np_x.sum() is also the sum of test.c_x
test.np_x[:] = 1
print test.np_x
print test.c_x[:5]
这输出:
[ 1. 2. 3. 4. 5.]
[1.0, 2.0, 3.0, 4.0, 5.0]
[ 1. 1. 1. 1. 1.]
[1.0, 1.0, 1.0, 1.0, 1.0]