Python调用C++ DLL库 ------OSError: [WinError 126] 找不到指定的模块。

Python调用C++ DLL库

解决Python中 OSError: [WinError 126] 找不到指定的模块 的问题。

一、问题:

  在进行Python开发的过程中,很可能遇到调用C++ DLL库的情况(为了提高效率),那么需要通过ctypes这个包,调用

  • ctypes.cdll.LoadLibrary(“path”)或者
  • ctypes.CDLL(“path”),

  然后可能就会碰到下面这个问题:大致意思就是找不到指定的库文件,但是这路径就是这样的。

在这里插入图片描述

Traceback (most recent call last):
  File "E:/WorkSpace/BT/DemoProject/main.py", line 28, in <module>
    LoadDll()
  File "E:/WorkSpace/BT/DemoProject/main.py", line 13, in LoadDll
    lib = ctypes.CDLL("E:\WorkSpace\BT\DemoProject\HelloWorld.dll")
  File "C:\Users\guoqing.zhang\AppData\Local\Programs\Python\Python37\lib\ctypes\__init__.py", line 364, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 126] 找不到指定的模块。

二、我尝试的解决办法

  • 在写路径时,尝试过单引号双引号斜杠反斜杠,但都不是引起这个的原因,
  • 怀疑是python安装包缺失的问题,然后就是去安装ctypes的库,安装一大堆之后也没有解决问题。

三、网上解决办法:

  • 说是位数问题,python是64位而生成的DLL库文件是32位,不匹配。
  • 说是编码问题,是ANSI和Unicode两种编码混淆,
  • 还有说是调用方式出现问题,有stdcall和cdecl两种方式导致问题出现
  • 尝试添加当前dll库路径:os.chdir(“E:\WorkSpace\BT\tool\Download\res”)
  • 可能是DLL依赖其他库文件,需要将其他库文件添加当前目录。(如何寻找所依赖的dll库 网上搜索到)

四、最终的解决办法:

  • Dll库的依赖问题,需要找出你用的DLL库所依赖的其他库文件,将其放到工程目录下即可。

  • 如果你在工程目录下还建立文件来放DLL库文件,则需要添加文件夹路径,通过这个函数:os.chdir(“E:\WorkSpace\BT\tool\Download\res”)
    在这里插入图片描述

  • 寻找库文件所依赖的其他DLL库文件,推荐使用Dependency Walker,可以找到你用的库所依赖的其他库文件,然后去Windows/system32下去找到所依赖的其他库文件。
    下载地址或者联系笔者邮箱
    在这里插入图片描述

  • 位数如果不匹配的话,报的错误不是126,而是193。这种情况直接重新使用x64重新编译生成64位的库文件即可。

Traceback (most recent call last):
  File "E:/WorkSpace/BT/DemoProject/main.py", line 28, in <module>
    LoadDll()
  File "E:/WorkSpace/BT/DemoProject/main.py", line 13, in LoadDll
    lib = ctypes.CDLL("E:\WorkSpace\BT\DemoProject\HelloWorld.dll")
  File "C:\Users\guoqing.zhang\AppData\Local\Programs\Python\Python37\lib\ctypes\__init__.py", line 364, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 193] %1 不是有效的 Win32 应用程序。

在这里插入图片描述
在这里插入图片描述

  • 如果是出现函数调用问题(stdcall和cdecl两种方式),应该不是找不到模块,而是找不到对应的函数,这里就用到了C++重载和C不支持重载以及extern “C”的东西,具体可以看笔者这篇文章。这种情况需要在dll库中的函数名声明时添加extern “C”修饰
    静态库(lib)与动态库(DLL)----函数重载的理解

笔者在调试的时候,尝试了一下,发现了这个情况。

DLL库程序:直接编译可形成DLL库。

#ifndef PCH_H
#define PCH_H

#include "framework.h"
#include "iostream"

#define LIB_API  __declspec(dllexport)

LIB_API void HelloWorld();
LIB_API int  Sub(int a, int b);

#endif 


#include "pch.h"
using namespace std;

LIB_API void HelloWorld()
{
    
    
	cout << "HelloWorld" << endl;
}


LIB_API int  Sub(int a, int b)
{
    
    
	return ((a)-(b));
}

Python调用程序:

def LoadDll():
    lib = ctypes.CDLL("E:\WorkSpace\BT\DemoProject\HelloWorld.dll")
    lib.HelloWorld()
    lib.Sub.argtypes = (c_int,c_int)
    lib.Sub.restype = c_int
    print(lib.Sub(3,1))
    return lib.Sub(3,1)

报错:
在这里插入图片描述

Traceback (most recent call last):
  File "E:/WorkSpace/BT/DemoProject/main.py", line 28, in <module>
    LoadDll()
  File "E:/WorkSpace/BT/DemoProject/main.py", line 14, in LoadDll
    lib.HelloWorld()
  File "C:\Users\guoqing.zhang\AppData\Local\Programs\Python\Python37\lib\ctypes\__init__.py", line 377, in __getattr__
    func = self.__getitem__(name)
  File "C:\Users\guoqing.zhang\AppData\Local\Programs\Python\Python37\lib\ctypes\__init__.py", line 382, in __getitem__
    func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'HelloWorld' not found

猜你喜欢

转载自blog.csdn.net/qq_34430371/article/details/112261682
今日推荐