ich bin neu hier und vorab einmal ein Gruß in die Expertenrunde. Arbeite jetzt seit ca. 10 Jahren mit Python und werde versuchen mich hier entsprechend einzubringen. Der Grund meiner Anmeldung ist aber, wie vermutlich bei den meisten hier, ein Problem was mich seit Tagen beschäftigt und ich hoffe sehr, dass mir hier jemand helfen kann.
Also, ich schreibe an einer C-DLL die als Schnittstelle zwischen Python und Java dienen soll. die DLL arbeitet mit einem Embedded Python Schnittstelle, was für reguläre Pythonfunktionen auch sehr gut funktioniert. Nun benötige ich aber die Möglichkeit Callbacks von C in Pythonfunktionen zu nutzen. D.h. ein Client ist mit der DLL verbunden und ruft doch eine Funktion auf mit Parametern auf, wovon einer eine C-Funktion ist. Die Umwandlung von normalen Datentypen wie int oder char * in Python Datentypen bringt Embedded Python von Haus aus mit sich (z.B. PyInt_FromLong(a);). Für Funktionen sieht das aber leider anders aus und die Dokumentation das Ganzen ist was das angeht leider auch sehr schlecht und in Teilen unvollständig. Ich habe zu dem Thema im Netz Folgendes gefunden (Quelle : http://stackoverflow.com/questions/1353 ... hon-with-c). Hier heißt es:
If you have a single C function that you want to provide as a callback, you can use PyCFunction_New to convert it into a Python callable:
Code: Alles auswählen
#include <python.h>
static PyObject *my_callback(PyObject *ignore, PyObject *args)
{
/* ... */
}
static struct PyMethodDef callback_descr = {
"function_name",
(PyCFunction) my_callback,
METH_VARARGS, /* or METH_O, METH_NOARGS, etc. */
NULL
};
static PyObject *py_callback;
...
py_callback = PyCFunction_New(&callback_descr, NULL);
This approach won't work if you want to choose different callbacks at run-time, e.g. to provide a generic c_to_python function that converts a C callback function to a Python callback. In that case, you'll need to implement an extension type with its own tp_call.
Code: Alles auswählen
typedef struct {
PyObject_HEAD
static PyObject (*callback)(PyObject *, PyObject *);
} CallbackObject;
static PyObject *
callback_call(CallbackObject *self, PyObject *args, PyObject *kwds)
{
return self->callback(args, kwds);
}
static PyTypeObject CallbackType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"Callback", /*tp_name*/
sizeof(CallbackObject), /*tp_basicsize*/
0, /*tp_itemsize*/
0, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
(ternaryfunc) callback_call, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT, /*tp_flags*/
};
PyObject *
c_to_python(PyObject (*callback)(PyObject *, PyObject *))
{
CallbackObject *pycallback = PyObject_New(CallbackObject, &CallbackType);
if (pycallback)
pycallback->callback = callback;
return pycallback;
}
1>os4es.c(17): error C2071: 'callback': Ungültige Speicherklasse
1>os4es.c(23): error C2440: 'return': 'PyObject' kann nicht in 'PyObject *' konvertiert werden
1>os4es.c(56): warning C4133: 'return': Inkompatible Typen - von 'CallbackObject *' zu 'PyObject *'
Den C2071 hatte ich so auch noch nicht und ich versuche noch rauszufinden wo genau das Problem liegt. Inwieweit ich das so verwenden kann, bisher auch noch unklar, aber mir erscheint der Gesamtansatz sehr schlüssig. Ist hier jemand der Ähnliches schgon einmal gemacht hat und mir dazu etwas sagen kann?
Darüber hinaus noch eine weitere Frage. Wenn ich eine C-Funktion habe, void callback(int,int), wie kann ich diese mit der Funktion c_to_python nutzen? Wäre ein Cast auf PyObject (*callback)(PyObject *, PyObject *) hier überhaupot möglich? Es ist kleider schon ein ganzes Weilchen her als ich mit C gearbeitet habe, insofern seht mir manche dumme Frage bitte nach. Vielen Dank und Gruß!