【问题标题】:Embedding python in cpp: How to get a C-pointer to a python function (not to a PyObject)?在 cpp 中嵌入 python:如何获取指向 python 函数(而不是 PyObject)的 C 指针?
【发布时间】:2018-08-23 09:33:32
【问题描述】:

我想为现有的 C++ 应用程序启用用户 python 插件的编写。主应用程序将使用 boost::signals2 发出信号,触发用户 python 代码的执行。我设置了一个工作示例,其中调用了用户 python 模块中的初始化方法。用户可以订阅调用“连接”方法的信号:

import ctypes
CALLBACK_VOID_FUNC = CFUNCTYPE(None)

def myVoidHandler():
    print("myVoidHandler (python)")

def initialize(myCHandle):
    global myCDll, callback1
    myCDll = ctypes.CDLL("CppEventsd",  handle = myCHandle)
    [...]
    callback1 = CALLBACK_VOID_FUNC(myVoidHandler)
    myCDll.connect(b"readyToGo", callback1)
    [...]

connect方法的签名:

extern "C" __declspec(dllexport) bool connect(char* signalName, void(*pF)())

现在可以像这样从 cpp 调用 python 函数 myVoidHandler:

pF();

但更重要的是,pF 可以连接到升压信号。

但是我想让用户免于经历这个(并且免于自己的支持请求,因为他们没有完全正确),所以我想通过使用函数的命名约定从 cpp 端连接 python 函数/插槽。 我可以轻松检索到 python 回调的 PyObjet 指针:

PyObject *pModule, *pDict, *pVoidHandlerF;
pModule = PyImport_Import(pName);
pDict = PyModule_GetDict(pModule);
pVoidHandlerF = PyDict_GetItemString(pDict, "myVoidHandler");

但是我不知道如何从 cpp 端获取实际的函数指针(相当于 pF)!在 python 到 Cpp 的转换中似乎正在进行一些转换。

有什么想法吗?

【问题讨论】:

  • 您可以创建自己的 C++ 函数来调用 pVoidHandlerF,而不是直接连接到 Python 函数指针,例如,使用 C++ lambda:sig.connect([=](){ PyObject_CallObject(pVoidHandlerF, NULL); });
  • 是的!无论如何,这是更好的解决方案,因为我还可以检查 PyObject_CallObject 的返回并在出现问题时打印有用的消息!我会同意的。
  • 好的,我已将评论移至答案。随意接受它:)

标签: python c++ python-embedding


【解决方案1】:

您可以创建自己的 C++ 函数,而不是直接连接到 python 函数指针,该函数使用 python C-API 来调用 python 函数。这是一个例子:

boost::signals2::signal<void(void)>& sig = [...];
PyObject* pVoidHandlerF = [...];
sig.connect([=]() {
    PyObject_CallObject(pVoidHandlerF, NULL);
});

这允许您在 C++ 端执行其他操作,例如,传递参数、返回值、检查错误等。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 2013-08-05
    • 2013-01-03
    • 2019-06-25
    • 1970-01-01
    • 2014-09-19
    相关资源
    最近更新 更多