在ctypes结构中访问np.array [英] Access np.array in ctypes struct

查看:94
本文介绍了在ctypes结构中访问np.array的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有动态分配数组的ctypes结构,即:

I have a ctypes Structure with dynamic allocated arrays i.e.:

array_1d_double=npct.ndpointer(dtype=np.double,ndim=1,
                               flags='CONTIGUOUS')
class Test(Structure):
    _fields_ = ("x", array_1d_double, ..)

test = Test()
do_some_init_in_c(  for example malloc)

如果我打印test.x以下输出:

If I print test.x I get the following output:

<ndpointer_<f8_1d_CONTIGUOUS object at 0x7f104dc0c3b0>

c结构大致如下:

structure Test_s{
    double *x;....
};

如何像numpy数组那样访问此元素?
是否有必要将数组分配为np.arrays而不是使用malloc?这样做的正确方法是什么?

How is it possible to access this element like an numpy array? Is it maybe necessary to allocate the arrays as np.arrays instead of using malloc? What would be the proper way to do this ?

推荐答案

一种方法,就是直接在python端分配numpy数组并表现出来

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>

您现在应该可以使用结构的 x 成员作为C代码中的普通双精度数组。

You should now be able to use the struct's x member as a normal double array in the C code.

编辑:

澄清一下:如果实例化没有参数的 Structure ,它将为其所有成员提供 NULL 指针。

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

如果使用N个参数实例化Structure,则这些参数将分配给前N个成员

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

如果要绑定numpy数组永久覆盖您的结构,可以覆盖 __ init __ 方法:

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]

输出结果:

[ 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]

这篇关于在ctypes结构中访问np.array的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆