获取非托管DLL路径以独立于版本加载Python

2024-04-18 23:42:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我寻找一种方法来检索安装在用户计算机中的dll的路径,但是路径的位置可能会根据用户决定安装它的位置而改变。找不到任何东西,所以我用自己的发现写了这篇文章(请随意添加自己的发现)

一些背景:

我正在编写一个将Python加载到C++中的模块(我的用户的机器在其路径中安装了Python,但是Python版本和路径可能在用户之间有所不同)

但是,我发现了两个问题:

  • 链接器创建dll版本依赖项,即使我使用的是任何Python3版本可用的函数(例如,Python3.6需要python36.dll)
  • 必须设置PYTHONPATH才能找到已安装的模块

对于第一个问题,我使用LoadLibrary在运行时加载适当的dll,但这仍然将配置的负担留给了用户(用户必须配置系统中的哪个dll,以及它的安装位置)。如果您的用户知道他的配置,则可以正常工作,而我的许多用户则不是这样

这让我想到了猜测:

我能够加载python3.dll(它位于python36.dll或python38.dll的旁边),我需要dll的路径来计算PTYHONPATH(并且可能使用python3版本来获得正确的dll,如python37.dll、python38.dll等)


Tags: 模块方法用户路径版本机器链接计算机
2条回答

首先,使用LoadLibraryA(或LoadLibraryW)加载库,然后使用GetModuleFileNameA(或GetModuleFileNameW)获取完整路径

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

    HMODULE pythonLib = nullptr;
    pythonLib = LoadLibraryA("python3.dll");
    if (pythonLib != nullptr) {
        char path[MAX_PATH];
        GetModuleFileNameA(pythonLib, path, MAX_PATH);
        std::cout << path << std::endl;
    }

我不认为有一种好方法可以允许使用不同的Python次要版本(如3.6或3.8),除非为Python定义一个stable ABI。然而,根据我的经验,这使得Python的子集很差,不支持像PyMemoryView这样的东西。如果可以将代码的Python部分隔离到自己的DLL中,我还建议使用delay load链接器标志。这样,您就可以拥有一个配置文件,在运行时读取Python库所在的位置,并从适当的路径加载它

相关问题 更多 >