JACH
JACH

Reputation: 1048

Get unmanaged DLL path to load Python independent of the version

I looked for a way to retrieve the path to a dll that is installed in the user's computer, but where the path could change depending on where they decided to install it. Couldn't find anything, so I wrote this with my own findings (feel free to add your own).

Some background:

I'm writing a module that loads Python into C++ (my users' machines have installed Python in their path, but the python version and path may vary between users)

However, I've found 2 issues:

For the first issue, I used LoadLibrary to load at run time the appropriate dll, but that still left the burden of configuration on the user (he had to configure which dll was in his system, and where it was installed). Works fine if your user knows about his configuration, which is not the case for many of my users.

So that brings me to the guessing:

I was able to load python3.dll (which is located right next to the python36.dll or python38.dll) and I needed the path to the dll to calculate PTYHONPATH (and potentially, use python3 version to get the right dll to use, like python37.dll, python38.dll, etc.)

Upvotes: 1

Views: 240

Answers (2)

Matt Eding
Matt Eding

Reputation: 1002

I don't think there is a nice way to allow for different Python minor versions (eg 3.6 or 3.8) unless you define a stable ABI for Python. However from my experience is that this makes for a poor subset of Python that doesn't support things like PyMemoryView. I would also suggest using delay load linker flags if you can isolate the Python part of your code to its own DLL. That way you can have a config file that reads where the Python library is located at runtime and load it from the appropriate path.

Upvotes: 1

JACH
JACH

Reputation: 1048

First, load the library using LoadLibraryA (or LoadLibraryW) and then use GetModuleFileNameA (or GetModuleFileNameW) to get the fullpath

//#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;
    }

Upvotes: 0

Related Questions