python - 处理 Ctypes 中的默认参数
问题描述
试图在下面包装一个像这样的函数。
int foo(int x=1)
{
x++;
return x;
}
如何使用 argtypes 处理默认参数?
解决方案
有一种技术ctypes
可以声明默认参数和输出参数,但是您必须以不同的方式实例化函数。
这是一个用于包装和制作 pythonic 的 C++ 函数:
#define API __declspec(dllexport)
extern "C" {
API int test(double first, double second, double* out) {
if(second == 0)
return 1; // error code for divide by zero
*out = first / second;
return 0;
}
}
测试.py:
from ctypes import *
dll = CDLL('./test')
INPUT = 1 # constants for paramflags below
OUTPUT = 2
# Sample function returns an error code,
# This function checks it and raises an exception instead.
def errcheck(result,func,args):
if result:
raise ZeroDivisionError()
return args
PROTOTYPE = CFUNCTYPE(c_int,c_double,c_double,POINTER(c_double))
# First parameter is a tuple of function name and dll reference.
# Second parameter is a tuple-of-tuples, the same length as number of arguments(3).
# The tuples are (type,name,default). Name and default are optional.
# names allow calling the function with named parameters.
# Output-only arguments (if any) are return as the result, as tuple if necessary.
# The normal return value is lost unless captured with errcheck.
test = PROTOTYPE(('test',dll),((INPUT,'first',5),(INPUT,'second',2),(OUTPUT,)))
test.errcheck = errcheck
print(test()) # 5 / 2 = 2.5
print(test(8)) # 8 / 2 = 4.0
print(test(second=5,first=10)) # 10 / 5 = 2.0
print(test(second=0)) # 5 / 0 ... exception!
输出:
2.5
4.0
2.0
Traceback (most recent call last):
File "C:\test.py", line 20, in <module>
result = test(second=0)
File "C:\test.py", line 7, in errcheck
raise ZeroDivisionError()
ZeroDivisionError
如果这看起来很复杂,包装函数也可以:
from ctypes import *
# Sample function returns an error code,
# This function checks it and raises an exception instead.
def errcheck(result,func,args):
if result:
raise ZeroDivisionError()
return args
dll = CDLL('./test')
dll.test.argtypes = c_double,c_double,POINTER(c_double)
dll.test.restype = c_int
dll.test.errcheck = errcheck
def test(first=5,second=2):
out = c_double()
dll.test(first,second,byref(out))
return out.value
print(test()) # 5 / 2 = 2.5
print(test(8)) # 8 / 2 = 4.0
print(test(second=5,first=10)) # 10 / 5 = 2.0
print(test(second=0)) # 5 / 0 ... exception!
(相同的输出)
推荐阅读
- python - 从电子邮件 imaplib 中删除额外数据
- react-native - 键盘在外部触摸时被关闭,并且 onPress() 首次无法正常工作
- python - Python上的左连接
- c# - 如何获取以我的表单为父级的窗口的当前标题?
- java - Checkstyle 无法满足抑制过滤器,这是为什么呢?
- javascript - 加快javascript游戏的线索播放
- java - Google Protobuf 验证错误
- java - 如何创建一个程序来读取 JAVA 中的 .diff 或 .patch 文件?
- css - AEM 6.5 版,是否可以合并类?
- javascript - Spring Security 拒绝提供静态内容(Javascript 文件)