微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用 ctypes

如何解决使用 ctypes

我正在为 C 扩展创建一个 Python 包装器,它是传感器的驱动程序。 我需要使用 Python 将 Ctrl-C 中断信号传递给驱动程序,以便它结束当前的采集阶段并且不会开始新的采集阶段。 我找到了这两个相关的主题Allowing Ctrl-C to interrupt a python C-extension Allowing Ctrl-C to interrupt a python C-extension 但是他们没有回答我的问题,因为我使用的是 Ctypes(见下文)。 有没有办法使用 Python 的线程或 ctypes 来中断 C 扩展。我想避免对 C 代码进行任何更改。 目标是停止无限循环功能

Python 代码

import signal
import ctypes 
import os 
import sys 

if __name__ == "__main__" :
    libname = os.path.abspath(os.path.join(os.path.dirname(__file__),"clib.so"))
    LIBC = ctypes.CDLL(libname)
    LIBC.main.argtypes = [ctypes.c_int,ctypes.POINTER(ctypes.c_char_p),]
    args=(ctypes.c_char_p * (len(sys.argv)-1))(str.encode(sys.argv[1]))
    LIBC.main(len(args),args)
    signal.signal(signal.SIGINT,lambda s,f:os.kill(os.getpid(),signal.SIGTERM))

C 代码

#include <stdlib.h>
#include <stdio.h>
#incluse <string.h>

void endless_loop()
{
    while(1){printf("Can't stop me ! \n");}
}
int main(int argc,char* argv[])
{
    endless_loop();
    return 0 ;
}

Makefile

all: test

clean:
    rm -f *.o *.so *.html

clib.so: clib.o
    gcc -shared -o clib.so clib.c -fPIC

clib.o: clib.c
    gcc -Wall -Werror clib.c -fPIC

test: clib.so
    chmod 777 pyclib.py
    python pyclib.py 2

谢天谢地,

解决方法

    LIBC.main(len(args),args)
    signal.signal(signal.SIGINT,lambda s,f:os.kill(os.getpid(),signal.SIGTERM))

如果您希望在 LIBC.main 运行时调用信号处理程序,则必须在调用 signal.signal 之前而不是在它返回之后安装它(通过 LIBC.main)。

但是,正如您所注意到的:它仍然不起作用。这是因为在 C 扩展运行时不会执行 Python 信号处理程序,并且由于 Python 主动安装了 SIGINT 处理程序,默认情况下 Ctrl-C 在这种情况下不起作用。为了让它中断程序,恢复默认信号行为:

    signal.signal(signal.SIGINT,signal.SIG_DFL)
    LIBC.main(len(args),args)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。