简体   繁体   中英

Python Ctypes: Loading C++ DLL - “module not found” or “function 'fn_123' not found”

I'm trying to load AND call functions from an already compiled (not by me) C++ DLL file.

I'm faced with two problematic scenarios:

  1. Loading DLL by using 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 

    which gives me the module not found 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. Loading the same DLL by using win32api.LoadLibraryEx() then 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 

    which is able to load the DLL.

    However, when attempting to call functions within this DLL, the following AttributeError is raised:

     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 

After extensive online research and consulting the Ctypes documentation, I have tried the following historical solutions:

  • Use Dependency Walker to check dependencies
  • Ensure all DLL dependencies are placed in the same directory
  • Add the DLL directory to system PATH
  • Ensure extern "C" is added to the C++ header file to prevent name mangling
  • Using keyword EXPORTED_FUNCTION in the C++ header file
  • Setting the current working directory in Python to that of the DLL file directory prior to loading DLLs

without any success...

I've also compiled my own SEPARATE 64-bit C++ DLL file (completely independent from the aa_Functions.dll file previously mentioned) in Microsoft Visual Studio 2010 in both Debug and Release modes, with test functions included inside.

This test DLL is able to be loaded, and its functions called successfully, per the following:

__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

With the expected console output:

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

I've spent the last several days on this issue and a point in the right direction would be tremendously appreciated.

The solution to my specific problem was:

  1. Ensure a proper installation of MATLAB
  2. Ensure the dependent MATLAB DLL (libmx.dll) directory is added to PATH and can be loaded using ctypes PRIOR to loading the actual DLL

In hindsight, this was a very straightforward issue - missing DLL dependency. But it can be a challenge to find the SPECIFIC missing DLL.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM