在Python-Ctypes中使用从C导入的函数时得到错误的类型



我想使用一个用C编写的函数,它可以将一个数字从一个范围映射到另一个范围:

//mapping a number <value> from 0 -> <max>  to 
//<wanted_min> -> <wanted_max>
float map3(float value, float max, float wanted_min, float wanted_max) {
return (( (value/max) * (wanted_max - wanted_min) ) + wanted_min);
}

当我在C中(在Visual Studio中)运行它时,它会输出所需的结果(在本例中为-0.8)。

但当我在python中运行它时(使用ctypes模块):

from ctypes import *
c_funcs = CDLL("./myf.so")
def map_num(value, Max, wanted_min, wanted_max):
x = c_funcs.map3(ctypes.c_float(value), ctypes.c_float(Max),
ctypes.c_float(wanted_min), ctypes.c_float(wanted_max))
print(type(x))
return x
print(map_num(10,  100, -1, 1))

输出:

<class 'int'>
4 

x的类型是int,我不明白为什么。

如果我使用普通的python,我会得到想要的结果(当然):

def map_num(value, Max, wanted_min, wanted_max):
return (((value  / Max ) * (wanted_max - wanted_min)) + wanted_min)
print(map_num(10,  100, -1, 1))

我得到了想要的结果,它是-0.8(例如在这种情况下)

很抱歉缺少PEP8,如有任何帮助,我们将不胜感激!

如果不将原型应用于函数,ctypes会假设参数和返回是int。请参阅指定所需的参数类型(函数原型)。你可以将你的功能原型化,这样就不需要重铸任何东西。

from ctypes import *
c_funcs = CDLL("./myf.so")
c_funcs.map3.argtypes = [c_float, c_float, c_float, c_float]
c_funcs.map3.restype = c_float
def map_num(value, Max, wanted_min, wanted_max):
x = c_funcs.map3(value, Max, wanted_min, wanted_max)
print(type(x))
return x
print(map_num(10,  100, -1, 1))

现在map3已经完全原型化了,如果它所做的只是调用C函数并返回其结果,那么就不需要中间的map_num函数了。

ctypes无法在这里推断返回类型,并假设它是int,因此需要显式设置它

只需在调用函数之前执行此操作

...
c_funcs.map3.restype = c_float
c_funcs.map3(...)

从文档https://docs.python.org/3/library/ctypes.html#return-类型

默认情况下,假定函数返回Cint类型。其他返回类型可以通过设置函数对象的restype属性来指定。

最新更新