Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用CFFI访问C中的Python dunder方法?_C_Python 3.x_Python Cffi - Fatal编程技术网

如何使用CFFI访问C中的Python dunder方法?

如何使用CFFI访问C中的Python dunder方法?,c,python-3.x,python-cffi,C,Python 3.x,Python Cffi,我尝试着用C语言创建一个简单的哈希表,我可以在Python中使用它(使用CFFI)。以下是相应的文件和相关代码 哈希表.h: typedef struct { size_t size; ... int cmp_function(const PyObject*, const PyObject*); } hash_table_t; build\u hash\u table.py: from cffi import cffi HEADER_FILE_NAME = "

我尝试着用C语言创建一个简单的哈希表,我可以在Python中使用它(使用CFFI)。以下是相应的文件和相关代码

哈希表.h

typedef struct {
    size_t size;
    ...
    int cmp_function(const PyObject*, const PyObject*);
} hash_table_t;
build\u hash\u table.py

from cffi import cffi

HEADER_FILE_NAME = "hash_table.h"
SOURCE_FILE_NAME = "hash_table.c"

ffi = FFI()

header = open(HEADER_FILE_NAME, "rt").read()
source = open(SOURCE_FILE_NAME, "rt").read()

ffi.set_source("hashtable.hash_table", header + source)
ffi.cdef(header)

if __name__ = "__main__":
    ffi.compile()
现在,到目前为止一切正常。但是,我想在哈希表中插入任何数据类型。如何访问C代码中接收到的任何对象?例如,假设我有一个Python类:

class Person():

    def __init__(self, name, id):
        self.name = name
        self.id = id

    def __eq__(self, other):
        return self.id == other.id
在哈希表中搜索
Person
对象时,如何访问
\uuuuueq\uuuu
方法?如上所述,我有一个通用的比较函数,声明为
intcmp_函数(constvoid*,constvoid*)。目标是每次我搜索一个对象时,我都可以知道该对象的
\uuuueq\uuuu
方法定义-在C端

希望我把问题说清楚,提前谢谢

见。避免将
PyObject*
与CFFI一起使用。正确的答案是保持
int-cmp_函数(const-void*,const-void*)。我假设您已经使用
ffi.new\u handle()
将对象转换为可以发送给C的
void*
等效对象(在
add\u to\u hash\u table()
方法等中)和
ffi.from\u handle()
方法等中)来读取它们(在
get\u from\u hash\u table()
方法等中)

要实现比较函数,可以使用Python中的
extern“Python”
声明一个函数,如上面的文档所示。然后将该函数用于结构中的
cmp\u函数
指针。在该Python函数中,您将收到两个参数,即两个
void*
。首先使用
ffi.from_handle()
将它们转换回原始Python对象,然后只使用普通Python——在您的例子中,如果x==y:return 1,则可能只使用
;否则:返回0
或类似值

在调用
ffi.new\u handle()
后,请注意保持Python对象的活动状态。它们的
void*
表示恰好存储在一些C结构中,这一事实并不能使它们保持活力


请注意,CFFI不太适合实现纯数据结构,因为与直接CPython-C-API方法相比,所有这些转换和多个存储都会增加开销。

对于那些可能正在寻找其他方法来比较C中Python对象的人,我找到了正确的解释方法。

您的对象不应该是
void*
,而是
PyObject*
,然后…@AnttiHaapala编辑,谢谢!它们不应该是常数。无论如何,访问需要CPython,在pypypy等中不起作用。如果我只使用它们进行比较,我为什么不希望它们是const?不管是哪种方式,我都同意代码只与CPython兼容——当然,知道一个更可移植的选项也很好:)很抱歉响应太晚了。我还没有看到
new\u handle
from\u handle
函数。“在Python中用
extern“Python”声明一个函数”
是指在C头文件中吗?至于比较函数,我需要知道如何比较C端的对象-如果我在哈希表中插入一个新元素,我需要知道该元素是否已经存在。因此我需要“检索”“Python中的比较函数。同时,我也认为CFFI不适合这项工作,这表示CFFI将提高可移植性。“谢谢你的提示:”引用:“例如,如果你的用例正在调用C库函数或系统调用,你应该考虑使用cType模块或CFFI库,而不是编写自定义C代码。”注意它是如何调用库或系统调用的,而不是实现纯数据结构的。用Python声明一个函数,使用
extern“Python”
:我的意思是在URL上详细记录。