使用CTYPE和线程时分段故障



我使用 ctypes为C库编写了Python包装器。一切都很好,直到我使用threading模块尝试。

这是复制它的一个小例子:

foo.c

#include <stdlib.h>
#include <assert.h>
char *foo_init() {
    char *result = (char*)malloc(sizeof(char));
    assert(result);
    return result;
}
char foo_get(const char* p) {
    return *p;
}
void foo_set(char *p, char value) {
    *p = value;
}
void foo_del(char *p) {
    free(p);
}

foo.py

import threading
import ctypes
libfoo=ctypes.CDLL('foo.so')
libfoo.foo_init.restype = ctypes.c_void_p
libfoo.foo_get.restype = ctypes.c_char
class Foo:
    def __init__(self):
        self.__obj__ = libfoo.foo_init()
    def get(self):
        return libfoo.foo_get(self.__obj__)
    def set(self, value):
        libfoo.foo_set(self.__obj__, ctypes.c_char(value))
    def __del__(self):
        libfoo.foo_del(self.__obj__)
x = Foo()
x.set(b'x')
print(x.get())
def compute():
    y = Foo()
    y.set(b'y')
    print(y.get())
t = threading.Thread(target=compute)
t.start()
t.join()

汇编:

gcc -Wall -shared -o foo.so -fPIC foo.c

执行:

export LD_LIBRARY_PATH=.
python3 foo.py

结果:

b'x'
[1]    8627 segmentation fault  python3 foo.py

我们在这里看到x.get()是正确打印的,而y.get()则进行分割故障。因此,似乎存在与ctypesthreading的问题。

请注意,如果我将y的初始化移动到compute函数之外,则程序正常退出。

此外,操纵指针的每个函数都会产生分割故障(例如,如果我只保留__init____del__功能,仍然存在崩溃)。

关于如何解决此问题的任何想法?

@user2357112在评论中给了我答案:添加(良好的)返回类型,参数类型很重要。

替换foo.py的开头通过以下解决问题:

libfoo.foo_init.restype = ctypes.POINTER(ctypes.c_char)
libfoo.foo_init.argtypes = []
libfoo.foo_get.restype = ctypes.c_char
libfoo.foo_get.argtypes = [ctypes.POINTER(ctypes.c_char)]
libfoo.foo_set.argtypes = [ctypes.POINTER(ctypes.c_char), ctypes.c_char]
libfoo.foo_del.argtypes = [ctypes.POINTER(ctypes.c_char)]

相关内容

  • 没有找到相关文章

最新更新