Python/C API project - compile to exe

63 views
Skip to first unread message

Maciej Trzuskowski

unread,
Jul 23, 2020, 2:32:30 AM7/23/20
to PyInstaller

I'm working on project where I am using Python/C API and C++. C++ is used for most part of application, mainly for gui (wxWidgets), while Python is used for calculations on large data sets, e.g. from files. I'm doing it in Visual Studio and when I run the project in IDE everything works fine, like I want it to. Also, the exe file that is created during the launch of the project in the visual studio, when it is in the same folder with the python .py file, also works as it should be. But what I want to achieve is a complete application contained in one exe.

While searching for a solution, I found various possibilities to create an exe from a python file. For example, PyInstaller which I tested for a simple "hello world" python file and it works. However, I don't know and can't find a solution how to combine the exe created in visual with a python file.

I hope that someone has done a similar thing before and I can find help here because I'm already losing my mind on it.

And, above all, is it possible?

bwoodsend

unread,
Jul 23, 2020, 6:54:08 AM7/23/20
to PyInstaller
Certainly it's possible. I'm not entirely sure what your doing. Normally when we glue C++ to Python we compile the C++ to either dll/so and load via ctypes or to pyd and import directly but you seem to be saying you've compiled your C++ to an exe? In which case I take it your using subprocess in your Python code to load it?

Maciej Trzuskowski

unread,
Jul 23, 2020, 8:10:11 AM7/23/20
to PyInstaller
To simplify my problem, I made a small project showing my use of python and c++. Without any ui, any wxWidgets, any file operations. Only simple console application executed python script. Here it is:
cppFile.cpp

#include <Python.h>
#include <iostream>

int main()
{
                PyObject *pModule, *pClass, *pArgs, *pInstance, *pMethod;

Py_Initialize();

std::cout << "FirstCPPString" << std::endl;

pModule = PyImport_ImportModule("PythonApplication1");
pClass = PyObject_GetAttrString(pModule, "Importer");
pArgs = Py_BuildValue("()");
pInstance = PyEval_CallObject(pClass, pArgs);

Py_DECREF(pModule);
Py_DECREF(pClass);
Py_DECREF(pArgs);

pMethod = PyObject_GetAttrString(pInstance,"start");
pArgs = Py_BuildValue("()");

PyEval_CallObject(pMethod, pArgs);

Py_DECREF(pInstance);
Py_DECREF(pMethod);
Py_DECREF(pArgs);
Py_Finalize();
std::cout << "SecondCPPString" << std::endl;
}

PythonApplication1.py
print ('FirstPythonString')

class Importer:
    def start(self):
        print('SecondPythonString')

And, when I start project in visual studio here is my result:

result.PNG

And after starting project in visual, I get exe file, as a result of compile. But it's only exe with cpp file. Without .py file placed in the same folder, I got an error after running exe. And what I want, is, let's say, combine existing exe with .py file to one exe. I hope I said it clear.


bwoodsend

unread,
Jul 23, 2020, 11:12:16 AM7/23/20
to PyInstaller

Ahh your embedding Python into C++. I’ve never done that so I probably can’t help much. I imagine your C++ program needs to be able to find python3.dll and all its dependents so it needs to be in either your PATH or your current working directory. And it will also need PythonApplication1.py to be separated from the PyInstaller exe.

If you PyInstaller PythonApplication1.py, compile your C++ code, then copy PythonApplication1.py and cppFile.exe into dist/PythonApplication1/. Then launch `cppFile.exe`. Don’t try to use --onefile with PyInstaller yet - I can show you how to turn it into a single file after we’ve got it working as a bundle first.

Maciej Trzuskowski

unread,
Jul 23, 2020, 2:45:17 PM7/23/20
to PyInstaller
Ok, I've done it. Now my folder "dist/PythonApplication1" looks like this:
->Many folder
->Many files
->PythonApplication1.exe
->cppFile.exe
->PythonApplication1.py

When I launch "cppFile.exe" I get the same result as in visual studio: 4 prints.
When I launch "PythonApplication1.exe" I get 1 print: FirstPythonString.

Chris Barker

unread,
Jul 23, 2020, 2:45:30 PM7/23/20
to pyins...@googlegroups.com
I don't think you want PyInstaller here. In fact, what you are doing is simply writing a C++ application, Python, in this case, is being used as a C library.

So what you need to do is bundle up your app like any C++ app, that is to say:

* It has to be linked to the Python libs
* It has to have access to the Python standard library
* It has to have access to your Python code

I'm sure it's *possible* to do all of that in a single exe file, but it's going to be hard. 

So I'd plan on making an installer that creates a folder that has your exe and anything you need in it.

BTW, I think you are making things harder on yourself than you could. As a rule, it's easier to call C++ from Python than the other way around (via ctypes, Cython, pybind11 etc.

And there already is wxPython for a wx GUI. As the GUI isn't usually the performance bottleneck, I'd write that in Python, too :-)

Good luck,

-CHB






On Thu, Jul 23, 2020 at 8:12 AM bwoodsend <bwoo...@gmail.com> wrote:

Ahh your embedding Python into C++. I’ve never done that so I probably can’t help much. I imagine your C++ program needs to be able to find python3.dll and all its dependents so it needs to be in either your PATH or your current working directory. And it will also need PythonApplication1.py to be separated from the PyInstaller exe.

If you PyInstaller PythonApplication1.py, compile your C++ code, then copy PythonApplication1.py and cppFile.exe into dist/PythonApplication1/. Then launch `cppFile.exe`. Don’t try to use --onefile with PyInstaller yet - I can show you how to turn it into a single file after we’ve got it working as a bundle first.

--
You received this message because you are subscribed to the Google Groups "PyInstaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyinstaller...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/pyinstaller/ace71e6b-cb01-4691-8b01-2eb3e6356a4fn%40googlegroups.com.


--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris....@noaa.gov

进陆

unread,
Jul 23, 2020, 11:04:33 PM7/23/20
to PyInstaller

legorooj

unread,
Jul 24, 2020, 1:43:11 AM7/24/20
to pyins...@googlegroups.com
Actually their program uses "Python.h", which means it doesn't require any DLL dependencies. With our bootloaders we load the functions from the DLL because it means the same bootloader works for multiple versions of python.

Legorooj


-------- Original Message --------

On Jul 23, 2020, 23:35, bwoodsend < bwoo...@gmail.com> wrote:

Ahh your embedding Python into C++. I’ve never done that so I probably can’t help much. I imagine your C++ program needs to be able to find python3.dll and all its dependents so it needs to be in either your PATH or your current working directory. And it will also need PythonApplication1.py to be separated from the PyInstaller exe.

If you PyInstaller PythonApplication1.py, compile your C++ code, then copy PythonApplication1.py and cppFile.exe into dist/PythonApplication1/. Then launch `cppFile.exe`. Don’t try to use --onefile with PyInstaller yet - I can show you how to turn it into a single file after we’ve got it working as a bundle first.

--

Maciej Trzuskowski

unread,
Jul 27, 2020, 12:01:45 PM7/27/20
to PyInstaller
Thanks for all the answers. I think I got a lesson for the future, to firstly check if something is possible and then do it. :) I'll check nuitka and shedskin, but I wonder if it will not be easier to rewrite python functions to c++ and stay with c++ only.

Chris Barker - NOAA Federal

unread,
Jul 27, 2020, 1:44:20 PM7/27/20
to pyins...@googlegroups.com



Thanks for all the answers. I think I got a lesson for the future, to firstly check if something is possible and then do it. :) I'll check nuitka and shedskin,

Also Cython — it can be used in “embedded” mode as well.


but I wonder if it will not be easier to rewrite python functions to c++ and stay with c++ only.

Or rewrite the C++ in Python. At this point you’ve done the opposite of what most folks do— written the non-computationally intensive GUI in C++, and the computational bits in Python :-)

Anyway, you CAN do what you want here. It’s just that pyinstaller isn’t quite the tool you need.

Look up how to distribute C++ apps with Python embedded-it certainly is done. 

Also, a third option is to keep most of your code the same, but make Python the “host”: so it’s the main application, and it calls your C++ code on startup. Then you could bundle it up with pyinstaller.

-CHB




--
You received this message because you are subscribed to the Google Groups "PyInstaller" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pyinstaller...@googlegroups.com.

Maciej Trzuskowski

unread,
Jul 28, 2020, 8:08:37 AM7/28/20
to PyInstaller
At this point you’ve done the opposite of what most folks do— written the non-computationally intensive GUI in C++, and the computational bits in Python :-)

Yeah, after answers and thinking about it, I know that maybe it's a little weird. :)

Because I need to finish my project quickly now and I know c++ very well, better than python, I decided yesterday to rewrite python's part to c++ and I almost done it, so for now I will leave the problem I asked about. 

But maybe I'll come back soon to sort it out and make a second version of a project.
Reply all
Reply to author
Forward
0 new messages