Umbrechen / Casting von C-Strukturen in der Cython-Python-Klasse
Ich mache mich gerade erst mit Cython vertraut und versuche, einige Strukturen aus einer C-Bibliothek in Python-Methoden und -Klassen umzuwandeln. Was ich nicht wirklich verstehe, ist, wie das Umwandeln von (initialisierten) C-Strukturen in die entsprechende Python-Klasse funktionieren sollte. Was fehle ich hier:
Ein Ausschnitt aus der C-Header-Datei:
struct test_struct {
int _something;
complex_struct* _another;
};
typedef struct test_struct test;
test *test_new(void);
int some_method(test **n, int irrelevant);
Entsprechender Ausschnitt aus meiner .pxd:
cdef struct test_struct:
pass
ctypedef test_struct test
test* test_new()
int some_method(test **n, int irrelevant)
Mein .pyx:
def do_something(int irrelevant):
cdef test* t = test_new()
ret = some_method(&t, irrelevant)
# Here comes the problem...
return <Test?>t
cdef class Test:
cdef test* _t
# cinit here and some methods here. No members except _t
Alles bis zur Rückgabe funktioniert einwandfrei. Ich erhalte einen korrekten Wert inret
usw. Aber die Besetzung in der return-Anweisung scheint falsch zu sein oder es fehlen weitere Informationen. Bei der Ausgabet = do_something(42)
Python-Segfaults.
Der segfault selbst ist überhaupt nicht hilfreich:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a9e74b in internal_print () from /usr/lib/libpython2.7.so.1.0
(gdb) bt
#0 0x00007ffff7a9e74b in internal_print () from /usr/lib/libpython2.7.so.1.0
#1 0x00007ffff7a81adb in PyFile_WriteObject () from /usr/lib/libp,ython2.7.so.1.0
#2 0x00007ffff7b19acb in sys_displayhook () from /usr/lib/libpython2.7.so.1.0
#3 0x00007ffff7a64c23 in PyObject_Call () from /usr/lib/libpython2.7.so.1.0
#4 0x00007ffff7af2ff7 in PyEval_CallObjectWithKeywords () from /usr/lib/libpython2.7.so.1.0
#5 0x00007ffff7af6f3b in PyEval_EvalFrameEx () from /usr/lib/libpython2.7.so.1.0
#6 0x00007ffff7af91b0 in PyEval_EvalCodeEx () from /usr/lib/libpython2.7.so.1.0
#7 0x00007ffff7af92b2 in PyEval_EvalCode () from /usr/lib/libpython2.7.so.1.0
#8 0x00007ffff7b11f9f in run_mod () from /usr/lib/libpython2.7.so.1.0
#9 0x00007ffff7b13ec0 in PyRun_InteractiveOneFlags () from /usr/lib/libpython2.7.so.1.0
#10 0x00007ffff7b140ae in PyRun_InteractiveLoopFlags () from /usr/lib/libpython2.7.so.1.0
#11 0x00007ffff7b1470e in PyRun_AnyFileExFlags () from /usr/lib/libpython2.7.so.1.0
#12 0x00007ffff7b24bcf in Py_Main () from /usr/lib/libpython2.7.so.1.0
#13 0x00007ffff746f000 in __libc_start_main () from /usr/lib/libc.so.6
#14 0x000000000040073e in _start ()
Wie Sie sehen können, diedo_something
Methode sollte ein Python-Objekt vom Typ Test zurückgeben. Was muss ich hinzufügen, um die Besetzung erfolgreich zu machen? Muss ich die Struktur manuell der Python-Klasse zuordnen? Gibt es Cython-Magie, die ich verwenden kann?