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
五、其他相关问题:

在这里插入图片描述
笔者打开一个xxx_db.so,提示libc++_shared.so 找不到,然后就想到需要看一下哪些库缺少,使用objdump
在这里插入图片描述
然后将笔者需要找到编译器编译时所需要的库,对应的其编译器版本的库
在这里插入图片描述
然后需要放到对应的库的目录下面,比如lib64目录等。
之后又碰到问题,笔者直接在python环境下导入xxx_db.so,发现还是不行,报如下错误:Pyinit_xxx_db 里面没有定义导出函数
在这里插入图片描述
咨询同事发现,原来不是所有的动态库都可以被导入,只有定义了初始化的函数才可以,所以只能通过ctype.CDLL导入,所以后续就可以使用了。
在这里插入图片描述

### 回答1: 关于"python3.7.4 oserror: [winerror 126] 不到指定模块"错误,通常这个错误是由于Python程序在导入某个模块不到指定模块而引起的。在Windows操作系统中,它可能是由于以下几个原因之一导致的: 1. 模块没有正确安装:请确保指定模块已经正确安装并且可以被Python解释器到。可以使用pip命令安装模块,例如:`pip install 模块名`。 2. 环境变量配置错误:请检查环境变量是否配置正确。在Windows系统中,可以通过以下步骤检查环境变量配置: - 右键点击“我的计算机”,选择“属性”。 - 点击“高级系统设置”。 - 在弹出的对话框中,点击“环境变量”按钮。 - 确保系统变量“Path”中包含Python的安装目录以及Python的Scripts目录。 3. Python版本不匹配:请确保所使用的Python版本和模块的版本是匹配的。有些模块可能不兼容某些Python版本,需要使用兼容的版本或者更新Python版本。 4. 模块文件损坏或缺失:请检查模块文件是否存在,以及是否完整。如果文件损坏或缺失,可以尝试重新安装模块。 如果以上方法均无效,可以尝试在互联网上搜索相关错误信息,查解决方案或者参考其他开发者的经验。 ### 回答2: Python 3.7.4 的 OSError: [WinError 126] 不到指定模块通常是因为某些模块依赖项未能被正确加载。这可能是由于以下几种原因导致的: 1. 模块未正确安装:请确保你已经正确安装了相应的模块。可以使用 pip 命令来安装所需的模块。 2. 环境变量问题:有时候,模块的路径未被正确添加到系统的环境变量中,因此 Python寻找模块时无法到。你可以尝试在系统的环境变量中手动添加模块所在的路径。 3. 模块版本不兼容:有时候,模块的旧版本可能与 Python 版本或其他不兼容。你可以尝试更新模块到最新的版本,或者选择与你当前 Python 版本兼容的版本。 解决这个问题的具体方法可能因为情况而有所不同。你可以尝试以下几个步骤来解决这个问题: 1. 确定你是否正确安装了相关的模块,如果没有,请使用 pip 命令来安装它们。 2. 检查系统的环境变量,确保模块所在的路径已被正确添加。 3. 尝试更新你使用的模块到最新的版本。 4. 如果问题仍然存在,你可以尝试重新安装 Python 或者重新安装相关的模块。 希望这些方法可以帮助你解决这个问题。如果问题仍然存在,请提供更多的详细信息,以便我们能够更好地帮助你解决这个问题。 ### 回答3: 这个错误通常出现在Python程序中尝试导入或使用一个不存在或不到模块时。Python解释器在执行导入操作时,会尝试在系统指定的路径中查相应的模块文件,如果没有到,就会抛出OSError异常,错误代码为winerror 126。 解决这个问题的方法有以下几种: 1. 确保要导入的模块已经正确安装:可以通过在命令行中运行“pip freeze”命令来查看已安装的模块列表,如果要导入的模块不在其中,可以使用“pip install”命令安装。 2. 检查模块名字的拼写:确保导入的模块名字没有拼写错误,Python是区分大小写的,所以要确保大小写匹配。 3. 检查模块路径:有时候程序在导入模块时可能会出现路径问题,可以尝试指定完整的模块路径进行导入。例如,如果要导入的模块位于自定义文件夹下的子文件夹中,可以使用"from custom_folder.sub_folder import module_name"语句导入该模块。 4. 确保模块可被到:在Windows系统中,可以在系统的环境变量中添加Python模块的路径,这样就可以确保Python解释器能够到要导入的模块。 总之,通过检查模块的安装、拼写、路径和环境变量等方面,可以解决这个错误。如仍然无法解决,建议尝试在Python社区或相应模块的官方论坛中搜索类似的问题,寻求更多的帮助和解决方案。
评论 42
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张一西

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值