CTypes错误加载调用另一个DLL的DLL
编辑:我在DLL调用Python C / API时发布了部分解决方案来解决这个问题。 这篇文章显示了所涉及的源代码,但似乎源代码不是问题。
我正在使用CTypes来调用在Windows中调用64位C DLL的NASM 64位DLL,但是当我尝试使用CTypes加载它时,我得到“[WinError 126]无法找到指定的模块。” 这两个DLL正确编译并链接在一起,没有编译器或链接器错误,但CTypes无法加载C dll。
我知道这个错误是因为从NASM dll中调用C dll,因为当我消除C调用时,CTypes会加载NASM dll。
研究表明这是一个路径问题。 C dll与NASM dll位于同一文件夹中,它们从该路径链接在一起。 我还将C dll复制到CTypes程序所在的Python文件夹中,但是没有修复它。 当C dll与NASM dll位于同一文件夹中时,为什么会出现路径问题?
NASM代码使用NASM编译并与GoLink链接。 C dll在MSYS2中编译并与GCC链接。
这是NASM代码:
; Header Section [BITS 64] [default rel] export Main_Entry_fn extern DllMain section .data align=16 lib_pass_value: dq 0 lib_return_value: dq 0.0 filename: db "Python_Program.py" modulename: db "Test_For_C_API" section .text Call_Modules_fn: ;______ mov rcx,filename mov rdx,modulename mov r8,[lib_pass_value] sub rsp,40 call DllMain add rsp,40 mov [lib_return_value],rax exit_label_for_Call_Modules_fn: mov rax,[lib_return_value] ret ; __________ Main_Entry_fn: push rdi push rbp mov rax,1234 mov [lib_pass_value],rcx call Call_Modules_fn exit_label_for_Main_Entry_fn: pop rbp pop rdi ret
以下是NASM / GoLink编译和链接字符串:
nasm -Z myfile.err -f Win64 C:\NASM_Test_Projects\Call_Modules\Call_Modules.asm -l myfile.lst -F cv8 -g -o C:\NASM_Test_Projects\Call_Modules\Call_Modules.obj GoLink Call_Modules.obj /debug dbg /dll msvcrt.dll kernel32.dll C_DLL-Code.dll
这是C代码:
#include #include long DllMain(char *filename, char *modulename, long input_value) { PyObject *pName, *pModule, *pDict, *pFunc; PyObject *pArgs, *pValue; long return_val; int i; Py_Initialize(); pName = PyUnicode_DecodeFSDefault(filename); pModule = PyImport_Import(pName); Py_DECREF(pName); pFunc = PyObject_GetAttrString(pModule, modulename); pArgs = PyTuple_New(1); pValue = PyLong_FromLong(input_value); PyTuple_SetItem(pArgs, 0, pValue); pValue = PyObject_CallObject(pFunc, pArgs); Py_DECREF(pArgs); Py_DECREF(pFunc); Py_DECREF(pModule); Py_XDECREF(pFunc); Py_DECREF(pModule); return_val = PyLong_AsLong(pValue); Py_DECREF(pValue); return (return_val); }
这是C头文件:
#ifndef C_DLL_Code_H #define C_DLL_Code_H #define EXPORT_DLL __declspec(dllexport) EXPORT_DLL long DllMain(char *filename, char *modulename, long input_value); #endif
以下是C dll的MSYS2 / GCC指令:
gcc -c C_DLL-Code.c -I "\msys64\mingw64\include\python3.6m" -o C_DLL-Code.obj gcc -shared -o C_DLL-Code.dll C_DLL-Code.obj -L "\msys64\mingw64\include\python3.6m" -lpython3.6m
这是Python ctypes程序:
def Test_C_API(): if os.path.exists(r"C:\NASM_Test_Projects\Call_Modules\Call_Modules.dll"): hDLL = ctypes.WinDLL(r"C:\NASM_Test_Projects\Call_Modules\Call_Modules.dll") CallName = hDLL.Main_Entry_fn CallName.restype = ctypes.c_int64 ret_ptr = CallName()
所以我的问题是这是一个路径问题,还是我在NASM dll和它调用的C dll之间的接口中做错了什么? 他们编译和链接没有错误,所以我找不到问题。
非常感谢您的帮助。