我想使用一个用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-类型
默认情况下,假定函数返回C
int
类型。其他返回类型可以通过设置函数对象的restype
属性来指定。