我有两个不同的 C 函数,我想将它们与 Python 中的 ctypes 一起使用。
一个函数正在建立连接并返回指向结构的指针。该指针应用作第二个函数中的参数以重用已建立的连接。
C Code:
customStruct * connect()
{
customStruct *obj = connection_helper();
return obj;
}
void foo(customStruct * obj)
{
foo_helper(obj);
}
Python代码:
from ctypes import *
lib = CDLL("./test.dll")
obj = lib.connect()
lib.foo(obj)
不幸的是,当我调用时,我检索到访问冲突错误lib.foo()
。我可以重新创建customStruct
Python 中的结构体使用类_fields_
属性,但由于该结构由许多其他结构组成,并且由于我不想访问 Python 本身中的结构成员,因此我正在考虑如何创建可重用的标识符的替代方法。
我可以改变的定义connect()
也foo()
如我所愿。我还可以创建另一个“标识符”结构,如果这样我就不必在 python 中重新创建该结构。
Update:看来我必须使用该功能byref()
来实现我想要的。https://docs.python.org/3/library/ctypes.html#ctypes.byref
文档指出“返回的对象只能用作外部函数调用参数”,但我不确定要返回什么connect()
then.
如果你有一个不透明的结构(你不知道它的成员,或者不想知道它的成员),你仍然应该创建一个类来在 python 中表示该结构。然后,您可以使用此类来正确键入您的函数。这将有助于防止您意外地将错误的对象作为“CustomStruct”指针传递的错误。
例如:
from ctypes import cdll, c_int, c_void_p
mylib = cdll.LoadLibrary('mylib')
class CustomStructP(c_void_p):
# subclassing c_void_p creates an opaque pointer type that is distinct
# from c_void_p, and can only be instantiated as a pointer
pass
create = mylib.create
create.argtypes = [c_int]
create.restype = CustomStructP
display = mylib.display
display.argtypes = [CustomStructP]
display.restype = None
delete = mylib.delete
delete.argtypes = [CustomStructP]
delete.restype = None
obj = create(10)
display(obj)
delete(obj)
display(CustomStructP()) # passing a null pointer
现在,如果你尝试过类似的事情:display(c_void_p())
,你会得到:
Traceback (most recent call last):
File "C:\Users\User\Documents\python\src\main.py", line 31, in <module>
display(c_void_p())
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
我使用的C代码是:
#include <stdio.h>
#include <stdlib.h>
struct customStruct {
int val;
};
struct customStruct *
create(int val) {
struct customStruct *obj = malloc(sizeof(struct customStruct));
obj->val = val;
return obj;
}
void
display(struct customStruct *obj) {
if (obj) {
printf("customStruct(%d) @ %p\n", obj->val, obj);
}
else {
puts("customStruct is NULL");
}
}
void
delete(struct customStruct *obj) {
free(obj);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)