Unable to call custom module using Python/C API - python

File structure:
Foo/
list.so
main.cpp
list.cpp
boost_wrapper.cpp
main.cpp code:
#include <Python.h>
#include "list.cpp"
int main(int argc, char *argv[]){
PyObject *pimport;
pimport=PyString_FromString("list");
Py_SetProgramName(argv[0]);
Py_Initialize();
PyImport_Import(pimport);
/*PyRun_SimpleString("l=list.LinkedList()");
PyRun_SimpleString("l.insert(\"N\", 9)");
PyRun_SimpleString("l.display()");*/
Py_Finalize();
}
ERROR:
ImportError: No module named list
However if I run python from bash, I'm able to successfully import the module and use all functions defined. I've also tried to import using just PyRun_SimpleString with no avail.
I suspect the current working directory is invisible to the Python Interpreter called by Py_Initialize().

Add these lines after Py_Initialize(); to append your PYTHONPATH
PyRun_SimpleString("import sys");
PyRun_SimpleString("sys.path.append(\".\")");

Related

How to run Python code before `site` module is imported?

Is there a way to execute Python code before the site module is imported?
In case it matters, I'm asking because I'm running an embedded Python interpreter via Py_Initialize, and I'd like to configure the Python environment using Python code, however it's important this happens before the site module is imported since the changes impact how it initializes.
You can set Py_NoSiteFlag to suppress loading of site.py while initializing Python interpreter. site could be loaded later-on manually.
Here is a minimal example:
#define PY_SSIZE_T_CLEAN
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_NoSiteFlag = 1; /* Suppress 'import site' */
Py_Initialize();
PyRun_SimpleString("import sys; print('site' in sys.modules)\n");
//There are no site-packages in path:
PyRun_SimpleString("print(sys.path)\n");
// do what must be done
// ....
//now, import site manually,
//call site.main(), so site-packages are added to sys.path:
PyRun_SimpleString("import site; site.main()");
//now, site-packages are in path:
PyRun_SimpleString("print(sys.path)\n");
if (Py_FinalizeEx() < 0) {
exit(120);
}
return 0;
}
When running the resulting executable, one sees that site isn't loaded in Py_Initialize (first printed line is False) and is loaded later. We also need to call site.main() explicitly for site-packages to be put into sys.path.

import_array doesn't work in debug build in embedded Python C API

I have the following problem: I am using the embedded Python C API from C++ to execute Python code. Everything works so far in Release Mode, but as soon as I start to run the Debug Mode, I get the error:
ImportError: numpy.core.multiarray failed to import
when calling from C++:
Py_Initialize();
import_array();
Can anyone help me with that?
Thanks a lot in advance
Without seeing the full program code; if you check the docs, it recommends putting the line:
Py_SetProgramName(argv[0]); /* optional but recommended */
Before you make the Py_Initialize() function call.
"The Py_SetProgramName() function should be called before Py_Initialize() to inform the interpreter about paths to Python run-time libraries"
Make sure your main function has the argv argument like the example in the docs.
#include <Python.h>
int main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print 'Today is',ctime(time())\n");
Py_Finalize();
return 0;
}

possible to compile python.exe without Visual Studio, with MinGw

I am trying to achieve things laid out on this page:
https://blogs.msdn.microsoft.com/pythonengineering/2016/04/26/cpython-embeddable-zip-file/
The code I am trying to compile is just this:
#include "Python.h"
int
wmain(int argc, wchar_t **argv)
{
return Py_Main(argc, argv);
}
In VisualStudio 15 I have to add the python/include and link to the python libs directories in the project and also add:
#include "stdafx.h"
and then it compiles and works fine. I'm just curious, is it possible to do this with mingw, or another open source C/C++ compiler?
If I place a file my_python.cpp which contains the following:
#include "include/Python.h"
int
wmain(int argc, wchar_t **argv)
{
return Py_Main(argc, argv);
}
in the root directory of a fresh 32-bit python 3.5 install (windows 7 x64), cd to that directory and try to run:
gcc my_python.cpp -Llibs -lpython35 -o my_python.exe
I get this error:
c:/mingw/bin/../lib/gcc/mingw32/5.3.0/../../../libmingw32.a(main.o):(.text.startup+0xa0): undefined reference to `WinMain#16'
Any way to fix this, get it running without Visual Studio?
The error is unrelated to Python. wmain is Visual Studio specific. GCC does not treat wmain as entry point, it just sits there as a function which never gets called.
GCC requires main or WinMain as entry point. If neither of those entry points is found, then the compiler will complain. So let's just use main as entry point.
Py_Main presumably expects wide character string input. CommandLineToArgvW will always provide that. Example:
#include <Windows.h>
#include "include/Python.h"
int main()
{
int argc;
wchar_t** argv = CommandLineToArgvW( GetCommandLineW(), &argc );
return Py_Main(argc, argv);
}
If you still get the same error, just provide WinMain entry point to make it happy
#include <Windows.h>
#include "include/Python.h"
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
int argc;
wchar_t** argv = CommandLineToArgvW( GetCommandLineW(), &argc );
return Py_Main(argc, argv);
}
Also note, *.lib files are usually for Visual Studio. GCC version expects library names with *.a extension.

Unable to import .so file present in a different directory using embedded Python

I am trying to import a .so file present in a different directory as a module using embedded Python, using the code:
#include <Python.h>
int main(int argc, char** argv){
PyObject *pimport, *pimport_sys;
pimport=PyString_FromString("moddy");
pimport_sys=PyString_FromString("sys");
Py_Initialize();
PyImport_Import(pimport_sys);
PySys_SetPath("/XYZ/NEWFOLDER/build/lib.linux-x86_64-2.7"); #Absolute path
PyImport_Import(pimport);
PyRun_SimpleString("my=moddy.Moddy()");
Py_Finalize();
}
But I always get the error ImportError: No module named moddy
But when I tried:
import sys
sys.path.append("/XYZ/NEWFOLDER/build/lib.linux-x86_64-2.7")
import moddy
It successfully imported.
Thanks in advance.

Building windows executable using pyqt with python embedded

I'm trying to make a windows application that runs some python code, more or less like what py2exe does but made by hand.
My application should run on windows without any external python dependencies (even the interpreter).
I've tested this (main.cpp):
#include <Python.h>
int main(int argc, char *argv[]) {
Py_SetProgramName(argv[0]);
Py_Initialize();
PyRun_SimpleString("print \"Test\"\n");
Py_Finalize();
return 0;
}
When a build this I get a .exe file which upon execution prints Test on the console.
So far so good, but now I'm trying to build a minimal PyQt application as well, for that I put on the same folder of my .exe application the files
QtGui.pyd, QtGui4.dll, QtCore.pyd and QtCore4.dll, this is main.cpp:
#include <Python.h>
int main(int argc, char *argv[]) {
Py_SetProgramName(argv[0]);
Py_Initialize();
PyRun_SimpleString("import QtGui as gui\n"
"\n"
"app = gui.QApplication([])\n"
"mw = gui.QMainWindow()\n"
"mw.show()\n"
"print \"Test\"\n"
"app.exec_()");
Py_Finalize();
return 0;
}
The problem is that when I run the built .exe file I got this error:
Traceback (most recent call last):
File "<string>", line 1, in <module>
SystemError: dynamic module not initialized properly
So I don't know what kind of initialization I need to do in order to use the .pyd files.
Finally these are my questions:
What I'm doing wrong?
If I need some kind of extra initialization, how could I do that and why it is needed? Maybe it's something inherent to the Qt bindings?
Should I copy another *pyd file to the working dir of the app?
Is this approach of using directly the .pyd files feasible? Or there is a better way to make an application like the one I want?
Note: I do not want to use any tool like py2exe, cx_Freeze, pyinstaller, etc. I want to build the app myself.

Categories

Resources