Search code examples
pythoncctypes

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


I wanted to use a function written in C which maps a number from one range to another:

//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);
}

which outputs the wanted result (-0.8 in this case) when I run it in C (in Visual Studio).

but when I run it in python (with the module 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))

output:

<class 'int'>
4 

the type of x is int, and I can't figure out why.

and if I use regular python I get the wanted result (of course):

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))

I get the wanted result which is -0.8 (for example in this case)

I'm sorry for the lack of PEP8, any help would be greatly appreciated !


Solution

  • If you don't apply a prototype to function, ctypes assumes that arguments and return are int. See Specifying the required argument types (function prototypes). You can prototype your function so that nothing needs to be recast.

    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))
    

    Now that map3 has been fully prototyped, there isn't a need for the intermediate map_num function if all it does is call the C function and return its result.