Pybind11:如何真正修复丢失 DLL 错误?

问题描述 投票:0回答:1

因此,我尝试通过一个简单的项目来学习 Pybind11,但是像往常一样,出现了问题,当我尝试通过 Python Shell 或文件导入模块本身时,我遇到了这个错误。

ImportError: DLL load failed while importing test_module: The specified module could not be found.

pybind 模块本身包含一个打印“Hello World”的函数。

#include <iostream>
#include <pybind11/pybind11.h>


void sayHello() {
  std::cout << "Hello World!\n"; 
}


PYBIND11_MODULE(test_module, m) {
  m.doc() = "This is momumental!";
  m.def("sayHello", &sayHello, "Function that prints Hello World");
}

CMake 文件也可以正常工作。

cmake_minimum_required(VERSION 3.10)
project("test_module")

set(EXECUTABLE_OUTPUT_PATH "../")
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_subdirectory(".extern/pybind11")

pybind11_add_module("test_module" main.cpp)
target_compile_options("test_module" PRIVATE "-static-libgcc" "-static-libstdc++")

当时,我不知道该怎么办,并且很沮丧,因为我不得不再次处理另一个“黑匣子”情况。如果您想仔细了解代码的结构,我已经在 github 上发布了该项目。 https://github.com/ProarchwasTaken/pybind_test

我尝试过的。

经过一番愤怒的互联网搜索后,我找到了一种方法 解决问题。这要归功于 pybind 存储库中的这个线程: https://github.com/pybind/pybind11/issues/2010

从线程来看,显然该错误意味着某些DLL 我的 pybind 模块需求丢失,我可以修复它的方法是添加 我的模块缺少的 DLL 的路径。

>>> import os
>>> os.add_dll_directory("C:\\MinGW\\bin") # The path where DLLs the customized pybind module needs are locating.
<AddedDllDirectory('C:\\MinGW\\bin')>
>>> import example
>>> example.add(1, 2)
3

我尝试在 Python Shell 中执行此操作,它起作用了......我玩了一下 通过使用 init.py 文件设置一个小包,以及 创建了一个存根文件,以便我的 LSP 和类型检查器知道该函数 存在并且不抱怨。

主要问题。

虽然该解决方案确实有效,但仍然存在一个问题。这不是真的 便携的。虽然我的 DLL 目录位于:“C:/msys64/mingw64/bin”, 不是每个人都会把自己的位置放在同一个地方。却又孤身一人 甚至还有 mingw64。

该模块仅适用于我的计算机。如果我想分发怎么办 我在做什么?如果其他人想使用它,他们必须编辑 代码本身用于下载他们不想下载的东西。

我认为解决该问题的唯一方法是找到 DLL 模块丢失,并将它们静态链接到模块二进制文件本身。 这样,就没有人需要处理 add_dll_directory 的废话了。

我尝试使用依赖项来追踪可能丢失的 DLL 沃克,但我能找到的唯一线索是: “ext-ms-win-oobe-query-l1-1-0.dll”。但我认为线索是 无关紧要,因为当我添加 DLL 目录时模块导入得很好 在测试.py中。所以我只能推断出无论该模块是什么 DLL 缺少的是在该目录中。

就像我说的,我很沮丧,因为我似乎是唯一的人之一 谁似乎有这个问题。我想知道你们是否有办法解决我的问题。

python c++ c++17 pybind11
1个回答
0
投票

好的大家,我已经找到解决问题的方法了!显然,该模块需要的DLL文件是“libwinpthread-1.dll”。一旦我知道了这一点,我所要做的就是在 cmake 文件中静态链接它。不过,为了安全起见,您可能还想链接“static-libgcc”和“static-libstdc++”。

target_link_libraries("test_module" PRIVATE -static -lpthread -static-libgcc -static-libstdc++)

一旦我这样做并编译了模块文件,我就可以导入模块而无需使用“os.add_dll_directory”!终于我可以继续做别的事情了!

© www.soinside.com 2019 - 2024. All rights reserved.