Error importing Boost Python module (function_impl_base9max_arityEv) - python

I am trying to build a hello world C++ Python extension using boost-python.
I got the following source code from https://www.mantidproject.org/Boost_Python_Introduction:
// test.cpp
#include <iostream>
#include <boost/python.hpp>
void sayHello()
{
std::cout << "Hello, Python!\n";
}
BOOST_PYTHON_MODULE(test) // Name here must match the name of the final shared library, i.e. mantid.dll or mantid.so
{
boost::python::def("sayHello", &sayHello);
}
However, when I try to compile using the following command:
g++ -fPIC -I/usr/include/python3.6m test.cpp -c
g++ -shared test.o -o test.so -I/usr/include/python3.6m -I/lib64/libboost_python3
This command compiles successfully the code and creates a library file test.so.
However, when I try to import the module in python3, I get the following error:
ImportError: /home/yt/C++/test.so: undefined symbol: _ZNK5boost6python7objects21py_function_impl_base9max_arityEv
The link Import Error on boost python hello program seems to suggest the command
I used above would solve the problem by adding -I/usr/include/python3.6m and -I/lib64/libboost_python3, but it does not.
What am I doing wrong?
Thanks!
OS: Fedora 29 x86_64

Thanks guys!
The problem was the linker command. The correct one is:
g++ -fPIC -I/usr/include/python3.6m test.cpp -c
g++ -L /lib64 -shared test.o -o test.so -lpython3.6m -lboost_python3
Now it works on Fedora 29

Related

Embedded python fails to compile on Raspberry Pi

I installed python 3.9.1 on my Raspberry Pi following the instructions here https://www.ramoonus.nl/2020/10/06/how-to-install-python-3-9-on-raspberry-pi/ and set it as the default python interpreter. I got my compiling and linking parameters for embedded Python following the instructions here https://docs.python.org/3.9/extending/embedding.html#compiling-and-linking-under-unix-like-systems
I tried a simple test with the following code (test.c) :
#include <Python.h>
int
main(int argc, char *argv[])
{
wchar_t *program = Py_DecodeLocale(argv[0], NULL);
if (program == NULL) {
fprintf(stderr, "Fatal error: cannot decode argv[0]\n");
exit(1);
}
Py_SetProgramName(program); /* optional but recommended */
Py_Initialize();
PyRun_SimpleString("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
Py_Finalize();
PyMem_RawFree(program);
return 0;
}
and then
gcc -I/usr/local/opt/python-3.9.1/include/python3.9 -I/usr/local/opt/python-3.9.1/include/python3.9 -Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -c test.c -o test.o
and
gcc -L/usr/local/opt/python-3.9.1/lib/python3.9/config-3.9-arm-linux-gnueabihf -L/usr/local/opt/python-3.9.1/lib -lcrypt -lpthread -ldl -lutil -lm -o test.o
and got
/usr/lib/gcc/arm-linux-gnueabihf/4.9/../../../arm-linux-gnueabihf/crt1.o: In function '_start': /build/glibc-P1SmLh/glibc-2.19/csu/../ports/sysdeps/arm/start.S:119: undefined reference to 'main' collect2: error: ld returned 1 exit status
Trying to compile the example at https://docs.python.org/3.9/extending/embedding.html#pure-embedding throws the same error. What could the problem be?
Edit:
After Expolarity's comment I changed the linker command to:
gcc test.o -L/usr/local/opt/python-3.9.1/lib/python3.9/config-3.9-arm-linux-gnueabihf -L/usr/local/opt/python-3.9.1/lib -lcrypt -lpthread -ldl -lutil -lm -o test
which seems to have worked but threw me a bunch of other errors:
test.o: In function main': /home/pi/Downloads/test.c:6: undefined reference to Py_DecodeLocale'
/home/pi/Downloads/test.c:11: undefined reference to Py_SetProgramName' /home/pi/Downloads/test.c:12: undefined reference to Py_Initialize'
/home/pi/Downloads/test.c:13: undefined reference to PyRun_SimpleStringFlags' /home/pi/Downloads/test.c:15: undefined reference to Py_Finalize'
/home/pi/Downloads/test.c:16: undefined reference to `PyMem_RawFree'
collect2: error: ld returned 1 exit status
This seems more serious. Any ideas?
After tttapa's answer over here it finally worked by adjusting the linker command as so:
gcc test.o -L/usr/local/opt/python-3.9.1/lib/python3.9/config-3.9-arm-linux-gnueabihf -L/usr/local/opt/python-3.9.1/lib -lcrypt -lpthread -ldl -lutil -lm -lpython3.9 -o test
Edit: Expolarity also answered correctly just after tttapa. Thanks a lot everyone!

Error while using python file generated from SWIG (generated from C++)

I have a .cpp (called trial.cpp) file as follows:
#include "trial.hpp"
int main()
{
cout << "hello";
return 0;
}
My header file (trial.hpp) is:
#include <iostream>
using namespace std;
I have a .i file (trial.i) as follows:
%module trial
%{
#include "trial.hpp"
%}
%include trial.hpp
I have used SWIG in the following manner in cmd to generate .pyd, .py, .o and .cxx files:
swig -c++ -python trial.i
g++ -c trial_wrap.cxx -I C:\Users.....Python\Python37\include
g++ -shared trial_wrap.o -o _trial.pyd -L
C:\Users.....\Python\Python37\libs -l
python37
The files are generated successfully
However when I open Python command prompt and run this:
from trial import *
main()
I get an error saying
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'main' is not defined
How can I resolve this issue?
Moreover, if I'm using another function name (say fn1()) instead of main(), I get the following error in the third command:
g++ -shared trial_wrap.o -o _trial.pyd -L
C:\Users.....\Python\Python37\libs -l python37
The error is:
undefined reference to fn1()
I'd like to use fn1() instead of main()
How can I solve this issue?
Fixed it!
Used these three statements instead:
swig -c++ -python trial.i
g++ -c trial_wrap.cxx trial.cpp -I C:\Users\ngoyal\AppData\Local\Programs\Python\Python37\include
g++ -shared -o _trial.pyd trial.o trial_wrap.o -L C:\Users\ngoyal\AppData\Local\Programs\Python\Python37\libs -l python37
Also had to change main() to a non reserved function name and gave the function definition in the header file.

Reference undefined to functions in python-dev header

I'm trying to embedding some Python code into C; It's the first time I do a thing like that.
Here is the simple code of my first attempt copied by a guide on internet:
#include <Python.h>
void exec_pycode(const char* code)
{
Py_Initialize();
PyRun_SimpleString(code);
Py_Finalize();
}
int main(int argc, char **argv) {
exec_pycode(argv[1]);
return 0;
}
So I've installed python3.4-dev package.
Then for having info for the linker I typed:
pkg-config --cflags --libs python3
Then I tried to compile my code:
gcc -std=c99 -o main -I /usr/local/include/python3.4m -L /usr/local/lib -lpython3.4m main.c
(according the command before)
but this is the result:
/tmp/ccJFmdcr.o: in function "exec_pycode":
main.c:(.text+0xd): reference undefined to "Py_Initialize"
main.c:(.text+0x1e): reference undefined to "PyRun_SimpleStringFlags"
main.c:(.text+0x23): reference undefined to "Py_Finalize"
collect2: error: ld returned 1 exit status
It would seem that there is a problem with linking phase, but I can't understend where is the problem seeing that i've passed to the linker the exact paths of the header and of the library. How can I solve that problem?
Try reordering your compilation command, such that all linking options are specified after your C source files:
gcc -std=c99 -o main -I /usr/local/include/python3.4m main.c \
-L /usr/local/lib -lpython3.4m

python termination error when ctypes dll calls printf

I am developing a python system with some core dlls accessed via ctypes. I have reduced the problem to this condition: execute a module that loads (no need to call) two dlls, one of which calls printf -- this error will occur in exit.
This application has requested the Runtime to terminate it in an
unusual way. Please contact the application's support team for more
information.
My environment:
- Windows 7, SP1
- Python 2.7.8
- MinGW v 3.20
This test case is adapted from a tutorial on writing dlls with MinGW:
/* add_core.c */
__declspec(dllexport) int sum(int a, int b) {
return a + b;
}
/* sub_core.c */
#include <stdio.h>
__declspec(dllexport) int sum(int a, int b) {
printf("Hello from sub_core.c");
return a - b;
}
prog.py
import ctypes
add_core_dll = ctypes.cdll.LoadLibrary('add_core.dll')
add_core_dll = ctypes.cdll.LoadLibrary('sub_core.dll')
> make
gcc -Wall -O3 -g -ansi -c add_core.c -o add_core.o
gcc -g -L. -ansi -shared add_core.o -o add_core.dll
gcc -Wall -O3 -g -ansi -c sub_core.c -o sub_core.o
gcc -g -L. -ansi -shared sub_core.o -o sub_core.dll
>python prog.py
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
and pops up a message dialog to the same effect: "python.exe has stopped working ...".
Note that the programs execute as expected and produce normal output. This error at termination is just a big nuisance I'd like to be rid of.
the same happens for:
Windows 7 Enterprise, SP1
Python 2.7.11
mingw32-g++.exe 5.3.0

Python extension: symbol(s) not found for architecture x86_64 error

I want to write a python extension in c. I work on Mac, I took a code from here:
#include <Python.h>
static PyObject* say_hello(PyObject* self, PyObject* args)
{
const char* name;
if (!PyArg_ParseTuple(args, "s", &name))
return NULL;
printf("Hello %s!\n", name);
Py_RETURN_NONE;
}
static PyMethodDef HelloMethods[] =
{
{"say_hello", say_hello, METH_VARARGS, "Greet somebody."},
{NULL, NULL, 0, NULL}
};
PyMODINIT_FUNC
inithello(void)
{
(void) Py_InitModule("hello", HelloMethods);
}
I compile it:
gcc -c -o py_module.o py_module.c -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7/
gcc -o py_module py_module.o -I/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7/ -lm
But I get this error:
Undefined symbols for architecture x86_64:
"_PyArg_ParseTuple", referenced from:
_say_hello in py_module.o
"_Py_InitModule4_64", referenced from:
_inithello in py_module.o
"__Py_NoneStruct", referenced from:
_say_hello in py_module.o
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [py_module] Error 1
How comes python doesn't support X86_64 architecture?
Two things:
You need to link your extension as a shared object (you're attempting to link an executable, which is why the linker is looking for main());
You need to link against the Python static library (-lpython).
Query the python env path with these commands:
$python-config --includes
-I/usr/include/python2.6 -I/usr/include/python2.6
$python-config --ldflags
-lpthread -ldl -lutil -lm -lpython2.6
generate .o file:
$ g++ -fPIC -c -I/usr/include/python2.6 -I/usr/include/python2.6 xx.cpp
generate .so file:
g++ -shared xx.o -o xx.so
Thanks to #NPE #glglgl and anatoly here is my Makefile:
DIR=/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7/
CC=gcc
CFLAGS=-I$(DIR)
ODIR=.
LIBS_DIR=/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/config/
LIBS=-lpython2.7
_DEPS =
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = py_module.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.c $(DEPS)
$(CC) -c -o $# $< $(CFLAGS)
py_module: $(OBJ)
gcc -shared $^ $(CFLAGS) -I$(LIBS_DIR) $(LIBS) -o $#
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
makefile template had been taken from here.
In order to find the paths, one may use python-config --ldflags
and python-config --includes

Categories

Resources