python-3.x - 在运行时动态创建 CFUNCTYPE
问题描述
在 Python 中使用 ctypes 时,是否可以创建具有特定签名的 CFUNCTYPE,例如
ctypes.CFUNCTYPE (ctypes.c_void_p, ctypes.c_char_p)
动态而不是在运行时硬编码?在 Windows 上使用 Python 3.7
我目前拥有的代码创建字符串,例如“ctypes.CFUNCTYPE (ctypes.c_void_p, ctypes.c_char_p)”然后使用 eval 来创建对象。
我希望能够构造一个 CFUNCTYPE 对象而不必使用 eval。动态执行它的重点是我不知道 CFUNCTYPe 的签名,除非运行时。
解决方案
这是一个可能的示例,它ctypes.CFUNCTYPE
从字符串返回 a 的实例:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import ctypes
import re
re_cfunc = re.compile(r"ctypes\.CFUNCTYPE\((.+)\)")
def functype_str_parser(functype_str: str):
match = re_cfunc.match(functype_str)
if not match:
return None
types_str = match.group(1) # e.g. "ctypes.c_void_p, ctypes.c_char_p"
argtypes = list()
restype = None
for i, type_str in enumerate(types_str.split(",")):
module, ctypes_type_str = type_str.split(".") # e.g. ["ctypes", "c_void_p"]
ctype_type = getattr(ctypes, ctypes_type_str) # e.g. <class 'ctypes.c_void_p'>
if i == 0:
# the first one is the return type of the CFUNCTYPE
restype = ctype_type
else:
argtypes.append(ctype_type)
return ctypes.CFUNCTYPE(restype, *argtypes)
if __name__ == '__main__':
s = "ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p)"
print(f"Input: {s}")
cfunc_type = functype_str_parser(s)
if cfunc_type is None:
# the string couldn't be parsed
exit(-1)
print(f"result: '{cfunc_type}'; type: {type(cfunc_type)}")
# these are protected attributes and should not be used; the following code demonstrates the parsing was correct.
print(f"restype: {cfunc_type._restype_}")
for i, argtype in enumerate(cfunc_type._argtypes_):
print(f"Argtype #{i}: {cfunc_type._argtypes_[i]}")
输出:
Input: ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p)
result: '<class 'ctypes.CFUNCTYPE.<locals>.CFunctionType'>'; type: <class '_ctypes.PyCFuncPtrType'>
restype: <class 'ctypes.c_void_p'>
Argtype #0: <class 'ctypes.c_char_p'>
推荐阅读
- visual-c++ - 使用 /external 编译器选项时,我们如何避免来自 Windows 标头的编译指示包警告?
- python - 如何在 tkinter 多框架应用程序中定位小部件(例如按钮、表格或条目)?
- arcore - 给定 2 个像素,如何使用 ARCore 计算实际距离?
- python - Python OpenSSL 指定 DNS 服务器
- python-3.x - 在 Spyder IDE 中使用 Python 装饰器
- web-scraping - 我需要帮助网络抓取评论部分
- r - 从水平到垂直数据框重塑,连接并创建新列
- javascript - d3 中的求和和数据操作问题
- r - 为什么 R 的 strftime 会返回上个月的午夜?
- netezza - Netezza 外部表修剪 0 后的小数