在C中调用从Python接收指向函数的指针的函数

时间:2018-07-23 14:20:08

标签: python c swig

我正在使用Swig从C源代码制作python库。 有一个函数接收C语言中的函数指针。我需要从Python调用它,但回调函数必须在Python中。 我见过的所有文档都使用C中的回调函数。

示例:

typedef double (*FeeCalculator)(Transaction* p);

void dealTransaction(Transaction* t, FeeCalculator feeCalculator);

我希望该函数在Python中可用。像这样:

def myFeeCalculator(tran):
    return trans.Sum * 0.1

def main():
   t = Transaction()
   dealTransaction(t, myFeeCalculator)

1 个答案:

答案 0 :(得分:0)

感谢Flexo。 这就是我所做的:

这是我最终所做的:

Swig:

%{

typedef double (*FeeCalculator)(Transaction* p);
typedef struct{
    FeeCalculator callback;
    void* context;
} FeeCalculatorCallbackAndContext;

void dealTransaction(Transaction* t, FeeCalculatorCallbackAndContext* feeCalculator);

double __WrapperCallback(Transaction * t, void* context){
    PyObject *pTransaction = SWIG_NewPointerObj(SWIG_as_voidptr(t), SWIGTYPE_p_Transaction, 0 );
    PyObject* feeCalc = (PyObject*)context;
    PyObject *result = PyObject_CallFunctionObjArgs(feeCalc, pTransaction, NULL);
    double r = PyFloat_FromDouble(result);
    Py_DECREF(result);
    return r;
}

%typemap(in) FeeCalculatorCallbackAndContext* (FeeCalculatorCallbackAndContext temp) {
  if (!PyCallable_Check($input)) SWIG_fail;
  temp.callback = __WrapperCallback;
  temp.context = $input;
  $1 = &temp;
}

%}

C:

void dealTransaction(Transaction* t, FeeCalculatorCallbackAndContext* feeCalculator){
    feeCalculator->callback(t, feeCalculator->context);
}

从Python调用:

import myLib

def myFeeCalculator(tran):
    return trans.Sum * 0.1

def main():
   t = Transaction()
   myLib.dealTransaction(t, myFeeCalculator)