在cython中传递指向结构的指针

2024-09-27 21:30:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图编写一个cython接口到腮腺炎求解器(zmumps)的复杂版本。我遇到了一些问题,因为我以前对C或cython都没有经验。{1}下面的示例^能得到UMPI的真实代码。在

我相信我的问题是指向ZMUMPS_复杂结构的指针。为了

到目前为止,我有以下内容(从pymumps中大量提到):

zmumps_.pxd:

from libc.string cimport strncpy

cdef extern from "mumps_c_types.h":

    ctypedef struct ZMUMPS_COMPLEX "ZMUMPS_COMPLEX":
        double   r
        double   i

cdef extern from "zmumps_c.h":

    ctypedef int MUMPS_INT

    ctypedef struct c_ZMUMPS_STRUC_C "ZMUMPS_STRUC_C":
        MUMPS_INT      sym, par, job
        MUMPS_INT      comm_fortran    # Fortran communicator 
        MUMPS_INT      n

        # Assembled entry
        MUMPS_INT      nz
        MUMPS_INT      *irn
        MUMPS_INT      *jcn
        ZMUMPS_COMPLEX *a

        # RHS and statistics 
        ZMUMPS_COMPLEX *rhs
        MUMPS_INT      infog[40]

    void c_zmumps_c "zmumps_c" (c_ZMUMPS_STRUC_C *)

zmumps_c.pyx

^{pr2}$

在python代码中,我可以使用

import zmumps_c
import numpy as np

MUMPS_STRUC_C = staticmethod(zmumps_c.ZMUMPS_STRUC_C)
id = MUMPS_STRUC_C()
x = np.r_[1:10]
id.irn = x.__array_interface__['data'][0]

但是,我不知道如何设置a或rhs的值。任何帮助都将不胜感激。在


Tags: 代码fromexternstructcythonintdoublecomplex
2条回答

实现这一目标的方法不止一种——这里有一种方法。在

下面的代码定义了ZMUMPS_COMPLEX的包装器。然后它为ZMUMPS_STRUC_C定义一个包装器,并为rhs属性使用__get__和{}方法,允许它接受ZMUMPS_COMPLEX包装。在

zmumps_c.pyx

cdef class ZMUMPS_COMPLEX:
    '''A wrapper for the ZMUMPS_COMPLEX struct'''
    cdef c_ZMUMPS_COMPLEX c_zm

    def __init__(self, double real, double imag=0):
        self.c_zm.r = real
        self.c_zm.i = imag

    property r:
        def __get__(self):
            return self.c_zm.r
        def __set__(self, value):
            self.c_zm.r = value

    property i:
        def __get__(self):
            return self.c_zm.i
        def __set__(self, value):
            self.c_zm.i = value

    def __repr__(self):
        return '({real}{imag:+}j)'.format(real=self.c_zm.r, imag=self.c_zm.i)

cdef class ZMUMPS_STRUC_C:
    '''A wrapper for the ZMUMPS_STRUC_C struct'''
    cdef c_ZMUMPS_STRUC_C ob
    cdef object _rhs

    property rhs:
        def __get__(self):
            return self._rhs
        def __set__(self, ZMUMPS_COMPLEX c):
            self._rhs = c
            self.ob.rhs = &c.c_zm

    def test(self):
        return (self.ob.rhs[0].r, self.ob.rhs[0].i,)

def main():
    z = ZMUMPS_STRUC_C()
    c = ZMUMPS_COMPLEX(-3.5, 2.0)
    z.rhs = c
    print z.rhs
    print z.test()
    c.r = 42.0
    print z.rhs
    z.rhs.i = -5.0
    print z.rhs

main()函数演示了这两个对象的行为。输出应如下所示:

^{pr2}$

我没有安装库,所以我使用下面的虚拟定义进行了测试:

zmumps_.pxd

cdef struct c_ZMUMPS_COMPLEX "ZMUMPS_COMPLEX":
    double r
    double i

cdef struct c_ZMUMPS_STRUC_C "ZMUMPS_STRUC_C":
    c_ZMUMPS_COMPLEX *rhs

设置.py

from distutils.core import setup
from Cython.Build import cythonize

setup(
    ext_modules = cythonize("example.pyx")
)

这可能有助于:

The following example lets you get at the C-level members of Python’s built-in “complex” object:

cdef extern from "complexobject.h":

    struct Py_complex:
        double real
        double imag

    ctypedef class __builtin__.complex [object PyComplexObject]:
        cdef Py_complex cval

# A function which uses the above type
def spam(complex c):
    print "Real:", c.cval.real
    print "Imag:", c.cval.imag

here抓取的。在

由于ZMUMPS_COMPLEX和内置的Py_complex结构具有完全相同的结构,因此您应该能够通过在这两种类型之间创建一个桥来实现这一点(使用typedefs和/或cast或一个将Py_复杂结构转换为ZMUMPS_复杂体的函数)。。。在

我很乐意帮忙,但我目前还没有安装腮腺炎。。。在

相关问题 更多 >

    热门问题