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!