Python Ctypes: загрузка C ++ DLL - «модуль не найден» или «функция 'fn_123' не найдена» - PullRequest
0 голосов
/ 24 мая 2018

Я пытаюсь загрузить и вызвать функции из уже скомпилированного (не мной) файла C ++ DLL.

Я столкнулся с двумя проблемными сценариями:

  1. Загрузка DLL с помощью CDLL ():

    from ctypes import *
    __path_aa_Fn_dll__ = r'C:\user\aacad_2017\aa_Functions.dll' # DLL file path
    aa_Fn_dll = CDLL(__path_aa_Fn_dll__) # load DLL
    

    , что дает мне модуль не найден OSError:

    Traceback (most recent call last):
    File "C:/user/aacad_2017/cadClass.py", line 189, in <module>
    aa_Fn_dll = CDLL(__path_aa_Fn_dll__)
    File "C:\Users\user\AppData\Local\Continuum\anaconda3\lib\ctypes\__init__.py", line 348, in __init__
    self._handle = _dlopen(self._name, mode)
    OSError: [WinError 126] The specified module could not be found
    
  2. Загрузка той же DLL с помощью win32api.LoadLibraryEx () затем CDLL ()

    aa_Fn_dll_handle = win32api.LoadLibraryEx(__path_aa_Fn_dll__, 0, win32con.LOAD_LIBRARY_AS_DATAFILE) # get DLL handle
    aa_Fn_dll = CDLL(__path_aa_Fn_dll__, handle=aa_Fn_dll_handle) # load DLL
    

    , который может загрузить DLL.

    Однако при попытке вызвать функции из этой DLL возникает следующая ошибка AttributeError:

    aa_Fn_dll.aaBIN2iv.restype = c_double # set function return type
    aa_Fn_dll.aaBIN2iv.argtypes = [c_double, c_double, c_double, c_double, c_double, c_double, c_double, c_char_p] # set function argument types
    aa_Fn_dll.aaBIN2iv(10, 10, 10, 10, 10, 10, 10, b"C") # call DLL function
    
    
    Traceback (most recent call last):
    File "C:/user/aacadMatlabWrap_2017_new_test/cadClass.py", line 196, in <module>
    aa_Fn_dll.aaBIN2iv.restype = c_double
    File "C:\Users\user\AppData\Local\Continuum\anaconda3\lib\ctypes\__init__.py", line 361, in __getattr__
    func = self.__getitem__(name)
    File "C:\Users\user\AppData\Local\Continuum\anaconda3\lib\ctypes\__init__.py", line 366, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
    AttributeError: function 'aaBIN2iv' not found
    

После обширных онлайн-исследований и ознакомления с документацией Ctypes, я попробовал следующие исторические решения:

  • Используйте Dependency Walker для проверки зависимостей
  • Убедитесь, что все зависимости DLL размещены в одном каталоге
  • Добавьте каталог DLL в систему PATH
  • Убедитесь, что extern "C" добавлен в файл заголовка C ++ для предотвращения искажения имени
  • Использование ключевого слова EXPORTED_FUNCTION в заголовке C ++file
  • Установка текущего рабочего каталога в Python на каталог каталога файлов DLL до загрузки DLL

без какого-либо успеха ...

У меня также естьскомпилировал мой собственный 64-битный DLL-файл C ++ для SEPARATE (полностью независимый от ранее упомянутого файла aa_Functions.dll) в Microsoft Visual Studio 2010 в режимах Debug и Release с включенными в него тестовыми функциями.

Эта тестовая DLLвозможность загрузки и успешного вызова его функций в соответствии со следующим:

__path_test_dll__ = r'C:\user\dllTest\x64\Release\dllTest.dll' # test DLL file path
test_dll = CDLL(__path_test_dll__) # load test DLL
test_dll.fn4.restype = c_void_p # set test DLL function return type
test_dll.fn4.argtypes = [c_double, c_double, c_double, c_char_p, c_bool] # set test DLL function argument types
test_dll.fn4(10, 12, 1, b"Pay", True) # make test DLL function call

с ожидаемым выводом на консоль:

Min_P * Rate == $10
Pay: 1 Min_P: 10 Max_P: 12 Iteration #: 1
Min_P * Rate == $11
Pay: 0 Min_P: 11 Max_P: 12 Iteration #: 2
Min_P * Rate == $12
Pay: 1 Min_P: 12 Max_P: 12 Iteration #: 3

Process finished with exit code 0

Последние несколько дней я потратил на эту проблемуи точка в правильном направлении была бы чрезвычайно признательна.

1 Ответ

0 голосов
/ 31 мая 2018

Решение моей конкретной проблемы было следующим:

  1. Обеспечить правильную установку MATLAB
  2. Убедитесь, что зависимый каталог MATLAB DLL (libmx.dll) добавлен в PATH и может бытьзагруженный с помощью ctypes PRIOR для загрузки фактической DLL

Оглядываясь назад, это было очень простой проблемой - отсутствие зависимости от DLL.Но это может быть проблемой, чтобы найти конкретную отсутствующую DLL.

...