Home > Mobile >  Reading "None" as return value using python function to interface dll
Reading "None" as return value using python function to interface dll

Time:11-24

I have some python code that interfaces with a dll (in C). I have two version of my python code. I would like to use my second versions of the code. However when I run the second version, when I print the return value the output is "None". In my first version the output is 1 and 0 respectively. I would appreciate if someone could point my mistake. Thanks

First version of code that returns 1 and 0

hello.py

import ctypes

class my_outer_class:

    def __init__(self):

        test = ctypes.WinDLL('C:\\Users\OneDrive\HelloWorld\HelloWorld\loc\Debug\HelloWorld.dll')

        self.py_function_1 = test.function_1
        self.py_function_1.argtype = (ctypes.c_uint8,ctypes.c_uint8 )
        self.py_function_1.restype = ctypes.c_int

        self.py_function_2 = test.function_2
        self.py_function_2.argtype = (ctypes.c_uint8,ctypes.c_uint8 )
        self.py_function_2.restype = ctypes.c_int

run_test.py

import hello
import ctypes

myapi = hello.my_outer_class()
            
result = myapi.py_function_1(123,123)
print(result)

result = myapi.py_function_2(123,123)
print(result)

1
0
>>> 

second version that prints None as output

import ctypes

class my_outer_class:

    def __init__(self):

        self.test = ctypes.WinDLL('C:\\Users\OneDrive\HelloWorld\HelloWorld\loc\Debug\HelloWorld.dll')

    def func_1(self, argtype, restype):
        self.py_function_1 = self.test.function_1
        self.py_function_1.argtype = (ctypes.c_uint8,ctypes.c_uint8 )
        self.py_function_1.restype = ctypes.c_int

    def func_2(self, argtype, restype):
        self.py_function_2 = self.test.function_2
        self.py_function_2.argtype = (ctypes.c_uint8,ctypes.c_uint8 )
        self.py_function_2.restype = ctypes.c_int

run_test.py

import hello
import ctypes

myapi = hello.my_outer_class()
            
result = myapi.func_1(123,123)
print(result)

result = myapi.func_2(123,123)
print(result)

None
None
>>> 

CodePudding user response:

You never call self.test.py_function_X.

import ctypes

class my_outer_class:
    def __init__(self):
        self.test = ctypes.WinDLL(...)

    def func_1(self, a, b):
        self.py_function_1 = self.test.function_1
        self.py_function_1.argtype = ( ctypes.c_uint8, ctypes.c_uint8 )
        self.py_function_1.restype = ctypes.c_int
        return self.py_function_1(a, b);              # Missing

That said, it doesn't make sense to do those first three lines each time func_X is called. I'm not sure what you're going for. Maybe you want the following:

import ctypes

class my_outer_class:
    def __init__(self):
        self.test = ctypes.WinDLL(...)

        self.py_function_1 = self.test.function_1
        self.py_function_1.argtype = ( ctypes.c_uint8, ctypes.c_uint8 )
        self.py_function_1.restype = ctypes.c_int

    def func_1(self, a, b):
        return self.py_function_1(a, b);

Or maybe you were trying to delay instantiation. I don't think there's any reason to do so. But if there is, you could use something like the following:

import ctypes

class my_outer_class:
    def __init__(self):
        self.test = ctypes.WinDLL(...)
        self.py_function_1 = None

    def func_1(self, a, b):
        if not self.py_function_1:
            self.py_function_1 = self.test.function_1
            self.py_function_1.argtype = ( ctypes.c_uint8, ctypes.c_uint8 )
            self.py_function_1.restype = ctypes.c_int

        return self.py_function_1(a, b);

CodePudding user response:

In your first example you are storing "py_function_1" and "py_function_2" as attributes in the class then you are directly calling those attributes through the use of:

myapi.py_function_1(123,123)
myapi.py_function_2(123,123)

These method directly return a value to you when called (as per your C code I assume). In your second example you aren't calling the attributes, you are calling methods you created in the class directly. Then when you do this your python methods (not your C code) have no return defined inside the method (therefor they return none). There are many ways you can slice this issue and here would be my take on it:

import ctypes

class my_outer_class:

    def __init__(self):

        # Initialize anything that has to do with USING your C
        # method in the __init__ method. BEFORE you call it elsewhere.
        # These only need to be defined once during the initialization
        # of your object not every time you call the function.
        self.test = ctypes.WinDLL('dll path here')
        
        self.py_function_1 = self.test.function_1
        self.py_function_1.argtype = (ctypes.c_uint8,ctypes.c_uint8 )
        self.py_function_1.restype = ctypes.c_int
        
        self.py_function_2 = self.test.function_2
        self.py_function_2.argtype = (ctypes.c_uint8,ctypes.c_uint8 )
        self.py_function_2.restype = ctypes.c_int

    # Now your able to define the functions that use the
    # functions we setup in the __init__ file.

    def func_1(self, val1, val2):
        return self.py_function_1(val1, val2)

    def func_2(self, val1, val2):
        return self.py_function_2(val1, val2)

Let me know if this helped or if you have any further questions!

  • Related