2010-10-01 36 views
5

Vì vậy, tôi sắp hoàn tất. Bây giờ tôi có mã làm việc gọi hàm python callback.SWIG chuyển đối số sang hàm gọi lại python

Điều duy nhất tôi cần bây giờ là cách chuyển đối số cho hàm gọi lại trăn.

callback.c của tôi là:

#include <stdio.h> 

typedef void (*CALLBACK)(void); 
CALLBACK my_callback = 0; 

void set_callback(CALLBACK c); 
void test(void); 

void set_callback(CALLBACK c) { 
    my_callback = c; 
} 

void test(void) { 
    printf("Testing the callback function\n"); 
    if (my_callback) (*my_callback)(); 
    else printf("No callback registered\n"); 
} 

callback.i của tôi là:

// An entirely different mechanism for handling a callback 

%module callback 
%{ 
typedef void (*CALLBACK)(void); 
extern CALLBACK my_callback; 

extern void set_callback(CALLBACK c); 
extern void my_set_callback(PyObject *PyFunc); 

extern void test(void); 
%} 

extern CALLBACK my_callback; 

extern void set_callback(CALLBACK c); 
extern void my_set_callback(PyObject *PyFunc); 

extern void test(void); 

%{ 
static PyObject *my_pycallback = NULL; 
static void PythonCallBack(void) 
{ 
    PyObject *func, *arglist; 
    PyObject *result; 

    func = my_pycallback;  /* This is the function .... */ 
    arglist = Py_BuildValue("()"); /* No arguments needed */ 
    result = PyEval_CallObject(func, arglist); 
    Py_DECREF(arglist); 
    Py_XDECREF(result); 
    return /*void*/; 
} 

void my_set_callback(PyObject *PyFunc) 
{ 
    Py_XDECREF(my_pycallback);   /* Dispose of previous callback */ 
    Py_XINCREF(PyFunc);   /* Add a reference to new callback */ 
    my_pycallback = PyFunc;   /* Remember new callback */ 
    set_callback(PythonCallBack); 
} 

%} 

%typemap(python, in) PyObject *PyFunc { 
    if (!PyCallable_Check($input)) { 
     PyErr_SetString(PyExc_TypeError, "Need a callable object!"); 
     return NULL; 
    } 
    $1 = $input; 
} 

Nó hoạt động tốt. Tôi nên làm gì để tôi có thể chuyển đối số cho my_callback? Bất kỳ trợ giúp nào sẽ được đánh giá cao!

Trả lời

3

Đối số cho cuộc gọi lại là đối số thứ hai cho PyEval_CallObject(). Ngay bây giờ bạn đang xây dựng một tuple rỗng, có nghĩa là "không có đối số". Vì vậy, thay đổi điều đó. Hiện tại bạn đang thực hiện:

arglist = Py_BuildValue("()"); /* No arguments needed */ 

bạn thay vì chuyển Py_BuildValue bất kỳ đối số nào bạn muốn hàm Python nhận được. Ví dụ: nếu bạn muốn chuyển số gọi lại một số nguyên, một chuỗi và một đối tượng Python bạn nhận được từ đâu đó, bạn sẽ làm:

arglist = Py_BuildValue("(isO)", the_int, the_str, the_pyobject); 
+0

Tôi không bao gồm định nghĩa cho the_int, the_str và the_pyobject trong ví dụ của tôi. Họ sẽ là những thứ * bạn * muốn vượt qua. Đó là một ví dụ. –

+0

Ồ .. Tôi cũng cần tạo ra khoảng trống tĩnh PythonCallBack (char * the_str). Nó đã làm việc! Cảm ơn bạn rất nhiều! – joon

Các vấn đề liên quan