如何使用CFFI访问C中的Python dunder方法?
我尝试着用C语言创建一个简单的哈希表,我可以在Python中使用它(使用CFFI)。以下是相应的文件和相关代码如何使用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 = "
哈希表.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上详细记录。