I am having trouble embedding Python in C++. I am using Mingw w64 gcc and 64 bit Python 2.7.11.
#include <Python.h>
int main(int argc, char *argv[]) {
Py_Initialize();
PyObject* pName = PyString_FromString("test");
Py_DECREF(pName);
Py_Finalize();
return 0;
}
Calls to compiler:
g++ "-IC:\\Python27\\include" -O0 -g3 -Wall -c -fmessage-length=0 -std=c++11 -o "src\\main.o" "..\\src\\main.cpp"
g++ "-LC:\\Python27\\libs" -std=c++11 -o pytest.exe "src\\main.o" -lpython27
The problem is that it segfaults in Py_DECREF. I have tried expanding the macros, and have traced segfault to the following statement:
((*(((PyObject*) ((PyObject *) (pName)))->ob_type)->tp_dealloc)((PyObject *) ((PyObject *) (pName))));
Turns out, tp_dealloc points to 0x1.
The same problem happens in the example code provided in Python docs:
https://docs.python.org/2/extending/embedding.html#pure-embedding
If I remove some of the calls to Py_DECREF(pName) and Py_DECREF(pArgs), code from the docs works as intended. Yet every example I've found on the web (including the one from the Python docs) does call Py_DECREF.
What could be the cause of this error? Could there be some inconsistency in my build environment?
So, apparently, something is wrong with my environment. I tried compiling the same code on another PC and there was no segfault anymore.
Related
I am trying to learn how to embed a Python interpreter into my C/C++ programs.
I like this concept because it may enable me to extend C programs at run time as well as enable users to write custom scripts/plugins.
Detailed instruction on embedding Python in C is provided at: https://docs.python.org/3/extending/embedding.html
I'm using example code provided in the Python documentation to figure out the mechanics involved:
embedded.c
#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;
}
The problem is I can't figure out how to compile it on Windows using gcc.
C:\Users\user\embedded_python> gcc embedded.c
embedded.c:2:10: fatal error: Python.h: No such file or directory
#include <Python.h>
^~~~~~~~~~
compilation terminated.
I think the problem is I need to link to the Python.h file, but I can't seem to get the compiler flags right:
C:\Users\user\Desktop\embedded_python>gcc -IC:\Users\user\AppData\Local\Programs\Python\Python38 -lPython38 embedded.c
embedded.c:2:10: fatal error: Python.h: No such file or directory
#include <Python.h>
^~~~~~~~~~
compilation terminated.
How can I get this program to compile on Windows (preferably with gcc/g++ to avoid Visual Studio bloat)?
In Linux, but I suppose if you activate your Bash from windows and can perform a work around. First you have to install python3-dev
Then use this command line where your file is located, to compile (test is your filename)
gcc -Wall test.c -o test $(pkg-config --cflags --libs python3)
I am trying to compile some C++ Code with OpenCv and Pybind with this header:
https://github.com/patrikhuber/eos/blob/v0.12.2/python/pybind11_opencv.hpp
This has worked for me before, so I don't think the header file is the Problem.
I can compile the code without problems, but when i try to import the created file to Python I get the following error:
ImportError: /usr/lib/libgtk-3.so.0: undefined symbol: g_mount_operation_set_is_tcrypt_hidden_volume
Here is the C++ Code:
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
#include <pybind11/pybind11.h>
#include "pybind11_opencv.hpp"
using namespace std;
namespace py = pybind11;
cv::Mat func(cv::Mat Image1,cv::Mat Image2)
{
return Image1;
}
PYBIND11_MODULE(pybind_module, m)
{
m.doc() = "Text";
m.def("func", &func, "Function",
py::arg("Image1"),
py::arg("Image2"));
}
I am guessing it's a problem with my setup (arch linux) since I got something similar working before and not even this minimal example is working.
I was able to solve the problem myself using the following compiler settings.
c++ -msse4 -O3 -Wall -shared -std=c++11 -fPIC -lopencv_imgcodecs `python3 -m pybind11 --includes` main.cpp -o executable`python3-config --extension-suffix` /usr/local/include/ -L/usr/local/lib/ -march=native
I guess there was a mistake in the previous compilation.
I was looking at here to see how to expose c++ to Python. I have built Python deep learning code which uses boost-python to connect c++ and python and it is running ok, so my system has things for boost-python alread setup.
Here is my hello.cpp code (where I used WorldC and WorldP to clearly show the C++ and Python class name usage in the declaration. I don't know why the original web page is using the same class name World to cause confusion to beginners.)
#include <boost/python.hpp>
using namespace boost::python;
struct WorldC
{
void set(std::string msg) { this->msg = msg; }
std::string greet() { return msg; }
std::string msg;
};
BOOST_PYTHON_MODULE(hello)
{
class_<WorldC>("WorldP")
.def("greet", &WorldC::greet)
.def("set", &WorldC::set)
;
}
and this is how I made hello.so
g++ -shared -c -o hello.so -fPIC hello.cpp -lboostpython -lpython2.7 -I/usr/local/include/python2.7
When I run import hello in python, it gives me this error.
>>> import hello
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: ./hello.so: only ET_DYN and ET_EXEC can be loaded
Can anybody tell me what's wrong?
(I'm using anaconda2 under my home directory for python environment, but since my deep learning code builds ok with boost-python, there should be no problem including boost/python.hpp in my system directory)
I've long forgotten about this problem and got to revisit this issue today.
I found two problems. The first problem was that I gave -c option which made the compiler only compile the source and not link. The second problem was that the library name was wrong(I search /usr/lib64 and there was libboost_python.so, so it should be -lboost_python instead of -lboostpython). So the correct way to build it is :
g++ -shared -o hello.so -fPIC hello.cpp -lboost_python -lpython2.7 -I/usr/local/include/python2.7
I found it runs ok in python. :)
I would like to use python embedded in a c++ application.
Here is my code:
#include <Python.h>
int
main(int argc, char *argv[])
{
Py_SetProgramName(argv[0]);
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print 'Today is',ctime(time())\n");
Py_Finalize();
return 0;
}
I have included in the c:\log\python27\include to get Python.h and also c:\log\python27\libs to have the corresponding linked library of python which is installed in c:\log\python27
It's compiling but not linking... Why?
I always have followings errors:
main.o:main.cpp:(.text+0x17): undefined reference to `_imp__Py_SetProgramName'
main.o:main.cpp:(.text+0x1e): undefined reference to `_imp__Py_Initialize'
main.o:main.cpp:(.text+0x34): undefined reference to `_imp__PyRun_SimpleStringFlags'
main.o:main.cpp:(.text+0x3b): undefined reference to `_imp__Py_Finalize'
You can use this simple command if you are using python3.5
g++ test.cpp -I/usr/include/python3.5 -lpython3.5m -o call_function
depending where your libraries are!
My friend has an application written in C that comes with a GUI made using GTK under Linux. Now we want to rewrite the GUI in python (wxpython or PyQT).
I don't have experience with Python and don't know how to make Python communicate with C. I'd like to know if this is possible and if yes, how should I go about implementing it?
Yes its possible to call 'C' functions from Python.
Please look into SWIG(deprecated) also Python provides its own Extensibility API. You might want to look into that.
Also google CTypes.
LINKS:
Python Extension
A simple example:
I used Cygwin on Windows for this. My python version on this machine is 2.6.8 - tested it with test.py loading the module called "myext.dll" - it works fine. You might want to modify the Makefile to make it work on your machine.
original.h
#ifndef _ORIGINAL_H_
#define _ORIGINAL_H_
int _original_print(const char *data);
#endif /*_ORIGINAL_H_*/
original.c
#include <stdio.h>
#include "original.h"
int _original_print(const char *data)
{
return printf("o: %s",data);
}
stub.c
#include <Python.h>
#include "original.h"
static PyObject *myext_print(PyObject *, PyObject *);
static PyMethodDef Methods[] = {
{"printx", myext_print, METH_VARARGS,"Print"},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC initmyext(void)
{
PyObject *m;
m = Py_InitModule("myext",Methods);
}
static PyObject *myext_print(PyObject *self, PyObject *args)
{
const char *data;
int no_chars_printed;
if(!PyArg_ParseTuple(args, "s", &data)){
return NULL;
}
no_chars_printed = _original_print(data);
return Py_BuildValue("i",no_chars_printed);
}
Makefile
PYTHON_INCLUDE = -I/usr/include/python2.6
PYTHON_LIB = -lpython2.6
USER_LIBRARY = -L/usr/lib
GCC = gcc -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -fPIC -DMAJOR_VERSION=1 -DMINOR_VERSION=0 -I/usr/include -I/usr/include/python2.6
win32 : myext.o
- gcc -shared myext.o $(USER_LIBRARY) $(PYTHON_LIB) -o myext.dll
linux : myext.o
- gcc -shared myext.o $(USER_LIBRARY) $(PYTHON_LIB) -o myext.so
myext.o: stub.o original.o
- ld -r stub.o original.o -o myext.o
stub.o: stub.c
- $(GCC) -c stub.c -o stub.o
original.o: original.c
- $(GCC) -c original.c -o original.o
clean: myext.o
- rm stub.o original.o stub.c~ original.c~ Makefile~
test.py
import myext
myext.printx('hello world')
OUTPUT
o: hello world
Sorry but i don't have python experience so don't know how to make Python communicate with C program.
Yes, that's exactly how you do it. Turn your C code into a Python module, and then you can write the entire GUI in Python. See Extending and Embedding the Python Interpreter.
If you have an option between C or C#(Sharp) then go with C# and use visual studio, you can build the GUI by dragging and dropping components easy. If you want to do something in python look up wxPython. Java has a built in GUI builder known as swing. You'll need some tutorials, but unless this program doesn't need to be portable just go with C# and build it in 10 minutes .
Also, you can write your code in C and export it as a python module which you can load from python. It`s not very complicated to set up some C functions and have a python GUI which calls them. To achieve this you can use SWIG, Pyrex, BOOST.