【问题标题】:C DLL to Python CallbackC DLL 到 Python 回调
【发布时间】:2014-01-27 11:54:30
【问题描述】:

我有一个 Visual C++ DLL。我在 DLL 中导出了一个 SetCallback(function-pointer)。 我使用此函数从 python2.7 脚本设置回调函数。我遵循 Python 文档中给出的内容。

from ctypes import *
def mypy_callback(number):
    print str(number)

d = cdll.LoadLibrary(r"myfunctions.dll")
callback_type = CFUNCTYPE(None, c_int )
d.SetCallback(callback_type(mypy_callback))

在我的 C 代码中

typedef void (*callback_function)(int);
void SetCallback(callback_function aCallback)
{
    py_callback = aCallback;
}

当我从 C DLL 调用这个函数时,像这样:py_callback(999),python 就崩溃了。 我可能做错了什么?

【问题讨论】:

  • 回调发生时callback_type变量是否还在作用域内?
  • 是的。 callback_type 的范围很广。并且排除了一些看似明显的错误,如原型、参数/返回值不匹配等。我的同事(远程工作)使用 C# 回调尝试了相同的 DLL,它对他有用。我不懂 C#,所以不知道将它与我的 python 代码进行比较是否有意义。
  • 它对我有用。我使用 VS2008 并在SetCallback 中插入了调用。您发布的代码不完整,因为它从不调用回调,这让我想知道还有什么可能。您能否在一个最小的、新创建的 C 项目中重现该问题?

标签: python c++ c dll callback


【解决方案1】:

下面的回调间接将解决这个问题:

d = cdll.LoadLibrary(r"myfunctions.dll")
callback_type = CFUNCTYPE(None, c_int )
callback = callback_type(mypy_callback)
d.SetCallback(callback)

【讨论】:

  • 非常感谢,但请解释一下为什么必须有一个回调变量?问题与它的范围有什么关系?
  • 好的,ctypes 文档中的这个注释解释说:“确保你保留对 CFUNCTYPE() 对象的引用,只要它们是从 C 代码中使用的。ctypes 不会,如果你不这样做,它们可能会被垃圾回收,从而在进行回调时使您的程序崩溃。”
猜你喜欢
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-07
  • 2023-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多