One way to do what you are talking about would be to just straight up allocate the numpy array on the python side and behave like it is a straight forward double array on the C side.
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>
You should now be able to use the struct's x
member as a normal double array in the C code.
EDIT:
To clarify: If you instantiate a Structure
with no arguments, it provides NULL
pointers for all its members.
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
If you instantiate the Structure with N arguments, those arguments will be assigned to the first N members of the Structure.
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
If you want to tie the numpy arrays to your struct permanently, you can override the __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]
This outputs:
[ 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]