Wrap C struct with array member for access in python: SWIG? cython? ctypes?

后端 未结 5 1112
囚心锁ツ
囚心锁ツ 2021-02-03 10:19

I want to access a C function that returns a struct containing double arrays (where the lengths of these arrays is given by other int members of the struct) from python. The dec

5条回答
  •  别跟我提以往
    2021-02-03 10:41

    An equivalent to the SWIG created module using ctypes looks as follows:

    from ctypes import *
    from numpy import *
    
    lib = cdll.LoadLibrary("_get_element.so")
    
    class ELEMENT(Structure):
        _fields_ = [("dim", c_int),
                    ("vertices", c_int),
                    ("quadrature_degree", c_int),
                    ("polynomial_degree", c_int),
                    ("ngi", c_int),
                    ("quadrature_familiy", c_int),
                    ("weight", POINTER(c_double)),
                    ("l", POINTER(c_double)),
                    ("n", POINTER(c_double)),
                    ("dn", POINTER(c_double))]
    
    cget_element = lib.get_element
    cget_element.argtypes = [c_int, c_int, c_int, c_int, POINTER(ELEMENT)]
    cget_element.restype = None
    
    def get_element(dim, vertices, quad_degree, poly_degree):
        e = ELEMENT()
        cget_element(dim, vertices, quad_degree, poly_degree, byref(e))
        weight = asarray([e.weight[i] for i in xrange(e.ngi)], dtype=float64)
        l = asarray([e.l[i] for i in xrange(e.ngi*e.dim)], dtype=float64).reshape((e.ngi,e.dim))
        n = asarray([e.n[i] for i in xrange(e.ngi*e.vertices)], dtype=float64).reshape((e.ngi,e.vertices))
        dn = asarray([e.dn[i] for i in xrange(e.ngi*e.vertices*e.dim)], dtype=float64).reshape((e.ngi,e.vertices,e.dim))
        return weight, l, n, dn
    

提交回复
热议问题