I have a C# application that call a windows dll (fbwflib.dll). From this dll is called a function (FbwfIsFilterEnabled) that require two parameter passed by reference.
In C# my code is:
public class FBWF_Utilities
{
[DllImport("fbwflib.dll", SetLastError = true)]
static extern UIntPtr FbwfIsFilterEnabled(
[MarshalAs(UnmanagedType.U1)]
ref bool currentSession,
[MarshalAs(UnmanagedType.U1)]
ref bool nextSession
);
[DllImport("fbwflib.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.U4)]
static extern uint FbwfEnableFilter();
[DllImport("fbwflib.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.U4)]
static extern uint FbwfDisableFilter();
public static bool IsEnabledCurrent()
{
bool xCurrent = false;
bool xNext = false;
if (IsInstalled())
{
try
{
FbwfIsFilterEnabled(ref xCurrent, ref xNext);
}
catch (Exception ex)
{
MessageBox.Show("FBWF IsEnabledCurrent exception:\n\n" + ex.Message);
return false;
}
}
return xCurrent;
}
Now I need to convert this code in Python code.
I have tried:
@staticmethod
def IsEnabled():
dllObject = ctypes.cdll.LoadLibrary(r'C:\Windows\System32\fbwflib.dll')
dllObject.FbwfIsFilterEnabled.argtypes = [ctypes.c_int, ctypes.c_int]
dllObject.FbwfIsFilterEnabled.restype = None
current = ctypes.c_int(0)
next = ctypes.c_int(0)
dllObject.FbwfIsFilterEnabled(ctypes.byref(current, 0), ctypes.byref(next, 0))
messagebox.showinfo("", "Current: " + current + "\n" + "Next: " + next)
but I have an error: ctypes.ArgumentError: argument 1: :wrong type
I have tried other parametrizations but without any good result.
What is the correct way to load a library with parameters by reference?
Other function without parameter work well:
@staticmethod
def EnableFilter():
dllObject = ctypes.cdll.LoadLibrary(r'C:\Windows\System32\fbwflib.dll')
dllObject.FbwfEnableFilter()
@staticmethod
def DisableFilter():
dllObject = ctypes.cdll.LoadLibrary(r'C:\Windows\System32\fbwflib.dll')
dllObject.FbwfDisableFilter()
that work fine without any error.
A small description of the function that give me some trouble is here: https://www.pinvoke.net/default.aspx/fbwflib.FbwfIsFilterEnabled
EDIT:
changing with ctypes.pointer as suggested from Luke (thanks) now I had a different error:
Procedure called with not enough arguments (8 bytes missing) or wrong calling convention
referred to line:
dllObject.FbwfIsFilterEnabled(ctypes.byref(current, 0), ctypes.byref(next, 0))
changing the line as:
dllObject.FbwfIsFilterEnabled(ctypes.POINTER(current), ctypes.POINTER(next))
I receive the error: Type error: must be ctypes type
that let me know that byref calling was the right way probably.
changing considering bool type as done on my c# code:
@staticmethod
def IsEnabled():
dllObject = ctypes.cdll.LoadLibrary(r'C:\Windows\System32\fbwflib.dll')
dllObject.FbwfIsFilterEnabled.argtypes = [ctypes.POINTER(ctypes.c_bool), ctypes.POINTER(ctypes.c_bool)]
dllObject.FbwfIsFilterEnabled.restype = None
current = ctypes.c_bool()
next = ctypes.c_bool()
dllObject.FbwfIsFilterEnabled(ctypes.byref(current), ctypes.byref(next))
messagebox.showinfo("", "Current: " + current + "\n" + "Next: " + next)
I receive the same error: Procedure called with not enough arguments (8 bytes missing) or wrong calling convention
I think that the solution is near but it seams that there is some detail missing
SOLUTION:
The solution finally come starting from
ctypes.windll.LoadLibrary
as suggested from Luke. I have removed argtypes and restype for now and after receiving c_long value that can be 0 or 1 a have obtained boolean condition.
The simple (I can say this now) code is:
@staticmethod
def IsEnabled():
dllObject = ctypes.windll.LoadLibrary(r'C:\Windows\System32\fbwflib.dll')
c = ctypes.c_int()
# dllObject.FbwfIsFilterEnabled.argtypes = [ctypes.pointer(ctypes.c_int), ctypes.pointer(ctypes.c_int)]
# dllObject.FbwfIsFilterEnabled.restype = ctypes.c_void_p
current = ctypes.c_int()
next = ctypes.c_int()
dllObject.FbwfIsFilterEnabled(ctypes.byref(current), ctypes.byref(next))
messagebox.showinfo("", "Current: " + str(bool(current)) + "\n" + "Next: " + str(bool(next)))
I hope that it can be usefull for others in order to not loose so many time like me around the solution that is near the initial code but that require hours to be fixed also because of the "nature" of this dll that required an embedded system and the installation of this particular library.
Many thanks