2011-01-17 15 views
1

私は、PyUFunc_FromFuncAndDataを使ってnum関数のジェネリック関数を作成するC関数をコンパイルするコードをいくつか持っています。私はufuncを作成するためにいくつかのcythonを書いてきましたが、私はそれを配布しようとしているので、可能ならばctypesを使ってやりたいと思います。私はユーザにコンパイルのステップを避けたいと思います。ctypesを持つPythonオブジェクトへのポインタを返す関数をラップする

問題はPyUFunc_FromFuncAndDataがPyObjectへのポインタを返すことです。それはPythonコードからオブジェクトとして使用することは可能ですか?

基本的に、私は、Python/ctypesのに次のcythonコードを変換できるようにしたいと思います:ctypes.py_objectするために、その機能の

from numpy cimport NPY_DOUBLE 
from libc.stdlib cimport malloc, free 

cdef extern from "numpy/ufuncobject.h": 
    ctypedef void (*PyUFuncGenericFunction) (char **, Py_ssize_t *, Py_ssize_t *, void *) 
    object PyUFunc_FromFuncAndData (PyUFuncGenericFunction *, void **, char *, int, int, int, int, char *, char *, int) 
    void import_ufunc() 

import_ufunc() 


cdef class UFuncWrapper: 

    cdef readonly object func 
    cdef object _llvm_func 
    cdef PyUFuncGenericFunction function 
    cdef char *types 
    cdef bytes name 

    def __init__(self, func, ufunc, long long ptr): 
     self._llvm_func = ufunC# keep a ref to prevent it from being gced 
     cdef int num_args = len(func.args) 
     self.types = <char*>malloc(sizeof(char)*(num_args+1)) 
     self.name = func.name 
     cdef int i 
     for i in range(num_args+1): 
      self.types[i] = NPY_DOUBLE 
     self.function = <PyUFuncGenericFunction>ptr 
     self.func = PyUFunc_FromFuncAndData(
      &self.function, 
      NULL, 
      self.types, 
      1, #ntypes 
      num_args, 
      1, 
      -1, # PyUFunc_None, 
      self.name, 
      self.name, #FIXME: __doc__ 
      0) 

    def __dealloc__(self): 
     free(self.types) 

    def __call__(self, *args): 
     return self.func(*args) 
+0

私はあなたがすでにobvoiusを試みたと思います - 'returned_pointerを使用して' '.restype' ctypes.POINTER(ctypes.py_object)への関数の属性'と間接参照を設定する[0] '? –

答えて

3

セットRESTYPE。次の例では、Python C-APIへの呼び出しを使用していますが、他のものでも同様に動作します。

import ctypes 
class Foo(object): 
    bar='baz' 

foo=ctypes.py_object(Foo) 
print 'Memory adress of Foo.bar object:', 
print ctypes.pythonapi.PyObject_GetAttrString(foo,'bar') # prints the pointer 

ctypes.pythonapi.PyObject_GetAttrString.restype = ctypes.py_object 

print 'Actual Foo.bar after we set restype correctly:', 
print ctypes.pythonapi.PyObject_GetAttrString(foo,'bar') # prints "baz" 
関連する問題