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

Getting the wrong type when using a function imported from C in Python - Ctypes

我想使用一个用 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这里无法推断出return类型,假定为int,所以需要显式设置

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

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

来自文档 https://docs.python.org/3/library/ctypes.html#return-types

By default functions are assumed to return the C int type. Other return types can be specified by setting the restype attribute of the function object.

如果您不将原型应用于函数,ctypes 会假定 arguments 和 return 是 int。参见 Specifying the required argument types (function prototypes)。您可以为您的函数制作原型,这样就无需重铸任何内容。

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 函数和 return 它的结果,则不需要中间 map_num 函数。