test.dll文件的功能代码:
double __cdecl add(int len,double array[]){}
(我已经在vc中测试过了)
python代码:
import ctypes
from ctypes import *
N=...
arr=(c_double*N)()
...
...
dll=CDLL("test.dll")
sum=dll.add(c_int(N),byref(arr))
print sum
但是python代码不起作用, 并且“sum”总是等于N.(例如,当N = 10时,它打印“sum = 10”) 怎么了?
答案 0 :(得分:9)
在ctypes中传递数组镜像在C中传递一个数组,即你不需要传递对它的引用,因为数组已经是对它的第一个元素的引用。
from ctypes import *
N = ...
arr=(c_double*N)()
dll=CDLL("test.dll")
sum=dll.add(c_int(N),arr)
print sum
在讨论与qsort的接口时,可以在callbacks section下的ctypes文档中看到这方面的一个例子。
编辑:根据David Heffernan的评论,您还需要dll.add.restype = c_double
,否则ctypes将假定返回的类型为c_int
。
答案 1 :(得分:0)
这里的问题是该函数被定义为
double __cdecl add(int len, double array[]) { }
但是,除非您为其指定返回值的类型,否则ctypes默认为int
。这类似于将C中的函数声明为
int __cdecl add(int len, double array[]);
由于声明和定义不匹配,因此您的代码具有未定义的行为,即:
- 定义的函数的类型与表示被调用函数的表达式(6.5.2.2)指向的类型(表达式)不兼容。
在这种特定情况下,您运行的是一个在寄存器中返回整数和浮点值的体系结构;但int
和double
返回值存储在不同的寄存器中。现在,在此ABI中包含类型int
的返回值的寄存器恰好包含N
作为剩余。正确的返回值包含在浮点寄存器中,但由于ctypes期望得到int
,所以它从未使用过。
因此,正确的解决方法是
dll.add.restype = c_double