У меня есть приложение на C #, которое вызывает Windows DLL (fbwflib.dll).Из этой dll вызывается функция (FbwfIsFilterEnabled), для которой требуется два параметра, переданных по ссылке.
В C # мой код:
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;
}
Теперь мне нужно преобразовать этот код в код Python.
Я попытался:
@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)
, но у меня есть ошибка: ctypes.ArgumentError: аргумент 1:: неправильный тип
Я пробовал другие параметризации, но безрезультатнорезультат.
Как правильно загрузить библиотеку с параметрами по ссылке?
Другие функции без параметров работают хорошо:
@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()
, которые работают без ошибок.
Небольшое описание функции, которая доставляет мне некоторые проблемы, находится здесь: https://www.pinvoke.net/default.aspx/fbwflib.FbwfIsFilterEnabled
РЕДАКТИРОВАТЬ:
меняется с помощью ctypes.pointer asпредложил от Луки (спасибо), теперь у меня была другая ошибка:
Процедура вызвана с недостаточным количеством аргументов (8 байт отсутствует) или неверное соглашение о вызовах
ссылается на строку:
dllObject.FbwfIsFilterEnabled(ctypes.byref(current, 0), ctypes.byref(next, 0))
изменяя строку следующим образом:
dllObject.FbwfIsFilterEnabled(ctypes.POINTER(current), ctypes.POINTER(next))
I rВыявите ошибку: Ошибка типа: должен быть тип ctypes
, который позволяет мне знать, что вызов byref был правильным способом.
изменение, учитывая тип bool, как было сделано в моем коде c #:
@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)
Я получаю ту же ошибку: процедура вызвана с недостаточным количеством аргументов (8 байтов пропущено) или неверное соглашение о вызовах
Я думаю, что решение близко, но кажется, что отсутствуют некоторые детали
РЕШЕНИЕ:
Решение, наконец, начинается с
ctypes.windll.LoadLibrary
, как это предлагается от Луки.Я удалил argtypes и restype на данный момент, и после получения значения c_long, которое может быть 0 или 1, получено логическое условие.
Простой (я могу сказать это сейчас) код:
@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)))
Я надеюсь, что это может быть полезно для других, чтобы не тратить так много времени, как я, на решение, близкое к исходному коду, но требующее исправления часов, также из-за "природы" этой библиотеки DLL, которая требовалавстроенная система и установка именно этой библиотеки.
Большое спасибо