python - 通过 Python 中的 c 函数传递和返回一个双精度数组
问题描述
我在我的 Python 代码中成功调用了一个 dll 库。所有的 By-Value 函数运行顺利。问题是我的 c 函数需要一个双精度数组的指针来返回结果。我不知道如何定义这个数组。
from ctypes import *
testlib = cdll.LoadLibrary(".\\testdll.dll")
def wrap_func(lib, funcname, restype, argtypes):
func = lib.__getattr__(funcname)
func.restype = restype
func.argtypes = argtypes
return func
test1 = wrap_func(testlib, 'testfun1', c_double, [c_double, POINTER(c_double), POINTER(c_char)])
test2 = wrap_func(testlib, 'testfun2', c_double, [c_double])
a = 2.5
b = Pointer(c_double)
tstr = Pointer(c_char)
d = test1(a, b, tstr)
print(b.values)
test1 有问题。test2 成功运行。原函数 test1 n C 为:
double testfun1(double x, double* y, char* str)
我希望函数的输出通过数组 b 恢复。错误是:
ctypes.ArgumentError: argument 2: <class 'TypeError'>: expected LP_c_double instance instead of _ctypes.PyCPointerType
任何人都可以帮助我吗?
解决方案
在 ctypes 中,POINTER(c_double)
是表示指向c_double
s 的指针的类。你要传递的不是这个类本身,而是这个类的一个实例。这就是您收到错误消息的原因,它的意思是“期望'pointer to double' 的实例而不是'pointer to double' 类型”。
由于 C 函数的这些参数没有关联的大小,我将假设它们是输入/输出参数,在这种情况下,您需要让它们指向真实对象。这应该有效:
b = c_double()
c = c_char()
d = test1(a, byref(b), byref(c))
如果它们是数组,您可以在 Python 中创建数组,然后使用POINTER
您找到的类来创建实例:
DoublePointer = POINTER(c_double)
CharPointer = POINTER(c_char)
b = DoublePointer.from_buffer(some_array)
d = test1(a, b, tstr)
如果将 C 函数的参数声明为c_char_p
,则可以直接在其中使用 Python 字符串,而无需将它们显式转换为指针。
推荐阅读
- api - 一个函数中的多个 API 获取请求
- ios - 函数式编程中非可选数组的可选对象
- google-apps-script - 对 dfareporting.ads.insert 的 API 调用失败并出现错误:12043:必须先将广告素材分配给广告系列,然后才能将其与广告相关联
- google-apps-script - 导航到 Google Apps 脚本中的不同页面
- typescript - 如何在树实体中找到关联的子分支?
- angular - 如何在展示性内容之外使用异步管道?
- r - 求一个变量的均值,取决于另一个变量,按第三个分组
- html - HTML 缩小会扼杀阅读器视图?
- shell - 运行 start-hbase.sh 时出现“Bad Substitution”错误
- javascript - 是否有关于如何从 NodeJS CJS + Babel 迁移到 NodeJS MJS 的策略?