从 ctypes 中的回调访问值
Accessing value from callback in ctypes
我正在使用Python/ctypes编写基于商业DLL的应用程序。此 DLL 读取平面文件并通过 struct
返回数据。相关的 C struct
s 如下所示:
struct System{
unsigned short user;
unsigned short version;
};
struct Message {
unsigned short header;
unsigned short data;
unsigned int messageType;
};
DLL 附带的 API 提供指向具有以下原型的函数的指针。此函数循环访问平面文件并调用接下来定义的Callback
:
typedef int (__stdcall *Process) (const char* filename, const char* base, unsigned int flags, int user, Callback stdcallback);
Callback
原型(上面的第五个参数)定义为:
typedef int (__stdcall *Callback) (const System* Sys, const Message* Msg);
在我的 python 文件中:
from ctypes import *
# using WinDLL for stdcall
lib = WinDLL('CVO.dll')
class System(Structure):
_fields_ = [('user', c_ushort),
('version', c_ushort)]
class Message(Structure):
_fields_ = [('header', c_ushort),
('data', c_ushort),
('messageType', c_uint)]
PROTO = WINFUNCTYPE(c_int, POINTER(System), POINTER(Message))
def py_callbck(Sys, Msg):
print Msg._type_.messageType
# return 0 to read the next line in the flatfile
return 0
Callback = PROTO(py_callbck)
pProcess lib.Process
pProcess.argtypes = [c_char_p,c_char_p,c_uint,c_int,PROTO]
pProcess.restype = c_int
pProcess(c_char_p('flat.ccf'),c_char_p(None),c_uint(0),c_int(0),Callback)
我的问题在于访问 DLL 传递给 Msg
结构的值。代码应该打印一个c_int
(0, 1, 2),但返回一个Field
类型,如下所示:
<Field type=c_ulong, ofs=136, size=4>
我知道平面文件正在处理中,因为我的 Python 代码打印出数百个 <Field ...>
语句,这是应该做的。
我的问题是我如何访问 DLL 推送到Msg
Structure
的值而不是返回<Field ...>
语句?
注意我对 ctypes 比较陌生,C 也很少,所以如果你发现定义任何东西的问题,请告诉我。例如,我知道返回和对象ctypes.pointer
和返回新类型的ctypes.POINTER
之间存在差异。当我使用ctypes.pointer
时,代码错误。
对于ctypes来说相对较新,你在这里做得很好。指针的 _type_
属性是对指向数据类型的引用。在这种情况下,它是 Message
.类属性messageType
是实例使用的数据描述符CField
。
相反,您要做的是取消引用指针以获取Message
实例。您可以使用[0]
下标或 contents
属性:
def py_callbck(Sys, Msg):
print Msg[0].messageType # Msg.contents.messageType
# return 0 to read the next line in the flatfile
return 0
请记住保留对Callback
的引用,以防止它被垃圾回收。当前,您将其引用为全局。没关系。
关于你调用pProcess
的方式,当你定义了argtypes
时,通常没有必要为简单类型手动创建ctypes对象。您可以更简单地使用以下方法:
pProcess('flat.ccf', None, 0, 0, Callback)
但要注意函数是否需要可写字符串缓冲区。在这种情况下,请使用 create_string_buffer
.这里没有必要,因为char *
参数都是const
的。
- 访问类C++ C 样式回调
- 为什么可以在没有实例变量的情况下访问静态回调方法中的静态成员变量?
- 使用参数的 C# 委托回调会导致从 DLL 调用时C++访问冲突
- 从触摸回调访问向量元素的方法时,不良访问错误
- 访问回调函数中的 QPushButton
- 如何从qmlregistersingletontype的回调中访问QML加载项目
- 从 NS3 中接收的回调访问 WiFiPhy
- 读取 Lambda 回调后的访问冲突
- 如何从回调方法访问自定义类成员
- 如何访问成员变量 sqlite 回调
- 如何访问带有静态回调的对象属性
- C到C#(从C#访问C DLL回调函数)
- 无法访问在 std 回调中传递的对象变量
- 访问作为WiFi侦听器回调成员函数一部分的类的成员
- C++如何通过回调方法访问成员变量
- 从 ctypes 中的回调访问值
- C++ 无法从回调函数中的"this"访问对象指针
- Qt 应用程序在从 <QUrl>NetworkAccessManager->get() 回调访问 QList<QLlnkedList* >时冻结
- 回调方法无法访问成员变量或实例
- 如何在第三方库调用的回调函数中传递/使对象/变量可访问