gpt4 book ai didi

python - 如何使用 Swig 中止调用 C 函数的 Python 脚本?

转载 作者:太空宇宙 更新时间:2023-11-03 23:32:41 25 4
gpt4 key购买 nike

我在尝试中止 Python 脚本时遇到问题,例如:

#!/usr/bin/python

import hello

hello.draw()

exit()

其中 draw() 是一个 C 函数。在这个函数中有一个循环来打印一些文本。我试过 CTRL-C 来打破它,但它不起作用。重要的是 C 代码不能修改!

有什么想法吗?

最佳答案

我整理了一个示例,说明您可以如何执行此操作。它允许扩充功能并从中逃脱,而无需修改它。例如,给定函数 foo(在我的测试中内联在 test.h 中):

void foo() {
while(1); // never returns
}

您可以使用信号和 siglongjmp 玩游戏。但是应该注意的是 you need to be very careful确保您只调用 async safe foo 中的函数,或者在任何不安全调用之前屏蔽信号并在任何不安全调用之后取消屏蔽它们。

然后我们可以包装函数并使用 %exception 注入(inject)一些额外的代码以允许信号退出函数:

%module test

%{
#include <setjmp.h>
#include <signal.h>

static sigjmp_buf timeout;

static void backout(int sig) {
siglongjmp(timeout, sig);
}

#include "test.h"
%}

%include <exception.i>

%exception {
if (!sigsetjmp(timeout, 1)) {
signal(SIGALRM,backout); // Check return?
$action
}
else {
// raise a Python exception
SWIG_exception(SWIG_RuntimeError, "Timeout in $decl");
}
}

void foo();

%exception;

这允许我们写:

import signal
import test

signal.alarm(5)
test.foo()

考虑到有关异步安全函数的注意事项,这按预期工作。我在这里使用了 SIGALRM,因为它允许我将所有内容独立保存在一个 Python 文件中。如果您愿意,可以使用另一个线程/进程和其他信号。

如果您将我的示例中的 SIGALRM 更改为 SIGINT(并且显然也没有引发 SIGALRM),它将与 Ctrl+C 一起工作 - 它不起作用的原因这是因为 how the default Python signal handlers work . Python 使用的默认处理程序只是设置一个标志并在底层调用将控制权返回给 Python 之后 处理信号,这巧妙地回避了整个异步安全问题。

关于python - 如何使用 Swig 中止调用 C 函数的 Python 脚本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12145494/

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