Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
I'm trying to embed Python in C++. This is my Python file (with the name EmbedTest.py):
from __future__ import division
class model:
def init(self,a,b):
self.a = a
self.b = b
def test_method(a,b):
m = model(a,b)
m.add(1)
print("a: ",a,"b: ",b)
return (a+b,a-b,a*b)
This is my C++ file (with the name EmbedTest.cpp and located in the same folder as EmbedTest.py)
#include <Python.h>
int main(int argc, char *argv[]) {
PyObject *pName, *pModule, *pFunc;
PyObject *pArgs, *pValue, *pValue_1, *pValue_2;
double sum,diff,prod;
double a = atof(argv[1]);
double b = atof(argv[2]);
Py_Initialize();
pName = PyUnicode_DecodeFSDefault("EmbedTest.py");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if(pModule != NULL) {
pFunc = PyObject_GetAttrString(pModule,"test_method");
if(pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(2);
pValue_1 = PyFloat_FromDouble(a);
pValue_2 = PyFloat_FromDouble(b);
if (!pValue_1) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
if (!pValue_2) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
fprintf(stderr, "Cannot convert argument\n");
return 1;
PyTuple_SetItem(pArgs, 0, pValue_1);
PyTuple_SetItem(pArgs, 1, pValue_2);
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
sum = PyFloat_AsDouble(PyTuple_GetItem(pValue,0));
diff = PyFloat_AsDouble(PyTuple_GetItem(pValue,1));
prod = PyFloat_AsDouble(PyTuple_GetItem(pValue,2));
printf("a: %f b: %f sum: %f diff: %f prod: %f",a,b,sum,diff,prod);
Py_DECREF(pValue);
else {
Py_DECREF(pFunc);
Py_DECREF(pModule);
PyErr_Print();
fprintf(stderr,"Call failed\n");
return 1;
} else {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr, "Cannot find function \"%s\"\n", argv[2]);
Py_XDECREF(pFunc);
Py_DECREF(pModule);
else {
PyErr_Print();
fprintf(stderr, "Failed to load \"%s\"\n", argv[1]);
return 1;
if (Py_FinalizeEx() < 0) {
return 120;
return 0; }
Compiling is fine. I use the flags suggested by python3.6-config --cflags
. Hence
gcc -c -I/home/MyFolder/anaconda3/include/python3.6m -Wno-unused-result -Wsign-compare -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -O3 -pipe -fdebug-prefix-map==/usr/local/src/conda/- -fdebug-prefix-map==/usr/local/src/conda-prefix -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -flto -DNDEBUG -fwrapv -O3 -Wall -Wstrict-prototypes EmbedTest.cpp
works fine.
However, when I try to link, I get a problem. I use the flags suggested by python3.6-config --ldflags
. Hence I try
gcc -o EmbedTest.o -L/home/MyFolder/anaconda3/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/home/MyFolder/anaconda3/lib -lpython3.6m -lpthread -ldl -lutil -lrt -lm -Xlinker -export-dynamic
.
However, I get the following error message:
/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o: In function `_start':
/build/glibc-6V9RKT/glibc-2.19/csu/../sysdeps/x86_64/start.S:118: undefined reference to `main'
collect2: error: ld returned 1 exit status
Any idea what goes wrong here?
–
–
–
–
You are not linking the .o file, you are outputing to it.
Change
gcc -o EmbedTest.o -L/home/MyFolder/anaconda3/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/home/MyFolder/anaconda3/lib -lpython3.6m -lpthread -ldl -lutil -lrt -lm -Xlinker -export-dynamic
gcc -o EmbedTest EmbedTest.o -L/home/MyFolder/anaconda3/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/home/MyFolder/anaconda3/lib -lpython3.6m -lpthread -ldl -lutil -lrt -lm -Xlinker -export-dynamic
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.