2011-07-08 5 views
10

Utwierdzam Pythona w bibliotece C++, którą robię. Chciałbym, aby użytkownicy mogli przekazywać funkcje C w postaci wskaźników funkcji PyObject* (fpFunc*)(PyObject*,PyObject*);, aby móc korzystać z tych funkcji we wbudowanym języku Python.Zbuduj PyObject * z funkcji C?

Mam więc wskaźnik funkcji i wiem, że jest możliwe, aby umieścić tę funkcję jako metoda A modułu używając PyMethodDef struct i przekazaniem go do Py_InitModule("module", ModMethods); a tym samym uzyskanie PyObject* module które można łatwo chwycić z funkcji.

Ale naprawdę doceniłbym możliwość tworzenia tej funkcji w locie bez konieczności ponownego tworzenia kolejnego modułu za każdym razem.

Zajrzałem do dokumentacji Pythona i niektórych nagłówków w Pythonie, aby myśleć o hackowatym sposobie robienia tego bez prawdziwego sukcesu ... ale zastanawiam się, czy istnieje bardziej konwencjonalny sposób robienia tego.

Z tego co zrozumiałem, każda funkcja należy do modułu, nawet __builtin__, więc domyślam się, że wymagałbym przynajmniej modułu.

Każdy pomysł, jak to osiągnąć?

+0

Nie jest dla mnie jasne, co masz na myśli. Dlaczego używasz wskaźnika funkcji? Kto to ustawia? –

+0

Tworzę bibliotekę C++, która osadza Pythona. Używam wskaźnika funkcji, ponieważ jest on przydatny do przekazania. (edytowałem mój post) – Manux

Odpowiedz

22

Znaleziono. Chociaż nie ma go w dokumentach i nie jest jednoznaczne w źródle.

PyObject* (*fpFunc)(PyObject*,PyObject*) = someFunction; 
PyMethodDef methd = {"methd",fpFunc,METH_VARARGS,"A new function"}; 
PyObject* name = PyString_FromString(methd.ml_name); 
PyObject* pyfoo = PyCFunction_NewEx(&methd,NULL,name); 
Py_DECREF(name); 

Działa. Mogę wywołać funkcję tak, jak zwykle nazywam obiekt funkcji Python. Jeśli jesteś ciekawy, wszystko, co znalazłem w dokumencie, dotyczyło Py_InitModule4 i modułów ładujących, więc poszedłem sprawdzić źródło Pythona i dowiedziałem się o PyCFunction, potem rozejrzałem się po dokumencie, ale nie mogłem znaleźć cokolwiek o PyCFunction_NewEx, więc musiałem sprawdzić źródło, aby upewnić się, że było tak, jak myślałem.