gpt4 book ai didi

python - 如何防止python在退出时取消分配ctypes回调?

转载 作者:行者123 更新时间:2023-12-04 18:03:16 25 4
gpt4 key购买 nike

假设我有以下共享库要由 ctypes 加载.它允许您注册一个回调以在程序退出时或您自己调用时调用:

#include <stdlib.h>
static void (*callback)(void);

void invoke_callback(void)
{
callback();
}

void set_callback(void (*new_callback)(void))
{
callback = new_callback;
}

void init(void)
{
atexit(invoke_callback);
}

然后假设我通过 ctypes 的魔法加载这个库:
import ctypes
shared = ctypes.CDLL('./test.so')

#a callback function
def callback():
print "callback invoked"

#register functions to run at exit
shared.init()
#set the callback function to invoke
shared.set_callback(ctypes.CFUNCTYPE(None)(callback))
#invoke the callback function
shared.invoke_callback()

#...callback also invoked here, right?

我希望它的输出类似于以下内容:
callback invoked
callback invoked

对我来说不幸的是,它看起来更像这样:
callback invoked
Segmentation fault

你问这是为什么?好吧,似乎到时候 atexit函数被调用时,python 解释器已取消分配先前包含回调的内存:
(gdb) backtrace
#0 0x000000000049b11d in ?? () <- uh-oh
#1 0x000000000046d245 in ?? () <- ctypes' wrapper?
#2 0x00007ffff6b554a9 in ?? () <- ctypes
from /usr/lib/python2.7/lib-dynload/_ctypes.x86_64-linux-gnu.so
#3 0x00007ffff6944baf in ffi_closure_unix64_inner ()
from /usr/lib/x86_64-linux-gnu/libffi.so.6
#4 0x00007ffff6944f28 in ffi_closure_unix64 ()
from /usr/lib/x86_64-linux-gnu/libffi.so.6
#5 0x00007ffff673e71d in invoke_callback () at test.c:6 <- me
#6 0x00007ffff6f2abc9 in __run_exit_handlers (status=0,
listp=0x7ffff72965a8 <__exit_funcs>,
run_list_atexit=run_list_atexit@entry=true) at exit.c:82
#7 0x00007ffff6f2ac15 in __GI_exit (status=<optimized out>) at exit.c:104
#8 0x00007ffff6f14b4c in __libc_start_main (main=0x497d80 <main>, argc=2,
argv=0x7fffffffe408, init=<optimized out>, fini=<optimized out>,
rtld_fini=<optimized out>, stack_end=0x7fffffffe3f8) at libc-start.c:321
#9 0x0000000000497ca0 in _start ()

现在,我的问题。我实际上试图绑定(bind)到包含多个在退出时调用的回调的较大的 C 代码库(我无法修改)。当测试程序退出时,这些当前会导致段错误。是否有可能防止这种情况发生?

最佳答案

我可能会迟到,但最近我遇到了类似的问题。基本上,回调正在被 Python 垃圾收集。如果你这样做:

callback_type = ctypes.CFUNCTYPE(None)
wrapped_callback = callback_type(callback)
shared.set_callback(wrapped_callback)

它应该解决段错误。

关于python - 如何防止python在退出时取消分配ctypes回调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31613626/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com