【问题标题】:Calling function in C that receives pointer to function from Python在 C 中调用函数,从 Python 接收指向函数的指针
【发布时间】:2018-12-31 00:55:02
【问题描述】:

我正在使用 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)

【问题讨论】:

  • 你能提供一个minimal reproducible example吗?
  • 谢谢,我加了一个例子。
  • 即使大部分代码是用 C 编写的,您是否只能为 Python 包装器编写一些 C++?只需一点点 C++ 就可以大大简化胶水

标签: python c swig


【解决方案1】:

感谢柔印。 这就是我所做的:

这就是我最终所做的:

痛饮:

%{

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-16
    • 2020-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多