2

I am working with the 3.6.4 source release of Python. I have no trouble building it with Visual Studio as a dynamic library (/MDd) I can link the Python .dll to my own code and verify its operation.

But when I build it (and my code) with (/MTd) it soon runs off the rails when I try to open a file with a Python program. A Debug assertion fails in read.cpp ("Expression: _osfile(fh) & FOPEN"). What I believe is happening is the Python .dll is linking with improper system libraries. What I can't figure out is how to get it to link with the correct ones (static libraries).

4
  • That's an assertion, not a run off the rails. It doesn't mean there are any link errors - you wouldn't be able to use either library if there were link errors, much less execute assertions in them. This means that the code is trying to read from a closed file or it's using file functions on socket handles. In Windows sockets aren't files. What source are you trying to build? Have you check how the Python binaries for Windows are built? Something tells me they use different functions Commented Jan 31, 2018 at 15:14
  • My code works fine if built with /MDd. Commented Jan 31, 2018 at 15:25
  • And the embeddable python.dll also works, and is available for download at python.org. What could have happened is that you linked against a library that uses file functions instead of socket functions. VS provides far better support for C++ than C - it's one of the best compilers for C++ while C was essentially abandoned until VS 2017. Maybe you'll have better luck with VS 2017. I'd check the build instructions for Windows first though. Commented Jan 31, 2018 at 15:35
  • A hint: "The solution has no configuration for static libraries. However it is easy to build a static library instead of a DLL. You simply have to set the "Configuration Type" to "Static Library (.lib)" and alter the preprocessor macro "Py_ENABLE_SHARED" to "Py_NO_ENABLE_SHARED". You may also have to change the "Runtime Library" from "Multi-threaded DLL (/MD)" to "Multi-threaded (/MT)". " Commented Jan 31, 2018 at 15:51

1 Answer 1

5

This is what I needed to do to build and use python statically embedded in another application.

To build the static python library (e.g., python36_d.lib, python36.lib)

  1. Convert ALL projects in the python solution (pcbuild.sln) to static. This is about 40 projects, so it may take awhile. This includes setting library products to be build as 'static lib', and setting all /MD and /MDd build options to /MT and /MTd.

  2. For at least the pythoncore project alter the Preprocess define to be Py_NO_ENABLE_SHARED. This tells the project it will be looking for calls from static libraries.

  3. By hook or crook, find yourself a pyconfig.h file and put it in the Include area of your Python build. It is unclear how this file is built from Windows tools, but one seems to be able to snag one from other sources and it works ok. One could probably grab the pyconfig.h from the Pre-compiled version of the code you are building. [By the way, the Python I built was 3.6.5 and was built with Windows 2015, update 3.]

Hopefully, this should enable you to build both python36.lib and python36_d.lib. Now you need to make changes to your application project(s) to enable it to link with the python library. You need to do this:

  1. Add the Python Include directory to the General->Include Directories list.
  2. Add the Python Library directories to the General->Library Directories lists. This will be ..\PCBuild\win32 and ..\PCBuild\amd64.
  3. Add the define Py_NO_ENABLE_SHARED to the C/C++ -> Preprocessor area.
  4. For Linker->input add (for releases) python36.lib;shlwapi.lib;version.lib and (for debugs) python36_d.lib;shlwapi.lib;version.lib.

And that should be it. It should run and work. But one more thing. In order to be able to function, the executable needs to access the Lib directory of the python build. So a copy of that needs to be moved to wherever the executable (containing the embedded python) resides. Or you can add the Lib area to the execution PATH for windows. That should work as well.

That's about all of it.

Sign up to request clarification or add additional context in comments.

3 Comments

There is a downside to all of this. The Python module system depends on dynamic libraries, so if you get this whole thing going, you won't be able to import modules that have a .dll associated with them that needs to be loaded. See: stackoverflow.com/questions/19560594/…
very true, however if the goal is to produce a standalone exe with no deps and no unpacking behavior, that is the main upside. You cannot do very much, you will have to disable site loading behavior, and cannot import much of anything.
Also wanted to say that the project builds, pretty much only the libraries after conversion (very few if any of the exes work, even after adjusting to /MT(d)), and I got this working with python 3.10.1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.