python c++ extension: symbol not defined error - python

I have a working c++ code that I want to wrap into a python module on Windows XP and Python 2.7. I have never done this before, so I looked into swig and distutils.
I created an interface file and a setup.py and compiled using
python setup.py build_ext -c mingw32
The script creates a module_wrap.cpp from my module.i and module.cpp file, and then creates a module_wrap.o and a module.o. The creation of module.o creates a bunch of Warnings for unused variables and deprecated char*, but it seems to work. Because the C++-code is not mine, I don't really want to get into these right now.
The last step is executing
g++.exe -shared -s build\temp.win32-2.7\Release\module_wrap.o build\temp.win32-2.7\Release\module.o build\temp.win32-2.7\Release\_module.def -LC:\Programme\Python27\libs -LC:\Programme\Python27\PCbuild -lpython27 -o build\lib.win32-2.7\_module.pyd
I get
Cannot export init_module: symbol not defined
error: command 'g++' failed with exit status 1
I googled a lot to this now, and I just can not find a solution to this problem. The previously created _module.def seems to try to export this init since it contains
LIBRARY _module.pyd
EXPORTS
init_module
Obviously this doesn't work, but I have no idea why. Can anyone help me out here?

I figured it out. The problem was the (not posted) interface file module.i for swig. There I named the module %module usemodule, whereas in the setup.py i named the module name=module. This way swig created an init_function, that did not match the name the created module was expecting it. In the end: just a typo...
Thanks for your support nevertheless!

Related

Py_Initialize undefined reference

I want to add python functions in C++ code.
I made a GUI in gtk (on the Raspberry PI) and now I want to work with a camera module which is easy to handle in python. (I want to start a video directly when I push a button.)
So I included the file Python.h
#include <python3.4m/Python.h>
#include <python3.4m/pythonrun.h>
then I thought it should work, but when I try to compile Py_Initialize()
I get the error:
undefined reference to Py_Initialize.
I think this is strange because, when I type in, there came the selection for Py_Initialize.
In terms of headers you should be fine, since it compiled but failed at linking.
Now you need to link against the Python libraries. The way this is done largely depends on what toolchain you are using.
Maybe you can see my answer in another question:
if with python 3.x installed, maybe this command can work:
g++ hw.cpp `/usr/bin/python3-config --cflags` `/usr/python3-config --ldflags`
By the way, you should check you gcc and python version.
As I know, if gcc version is 5.4 and python version is 3.7, it doesn't work.(python 3.5 >is work)
When you run /usr/bin/python3-config --cflags, in fact, it is the compile option.
Set the python include folder and it static lib on gcc command line and put the python dynamic lib on LD_LIBRARY_PATH. Before Py_Initialize(), do not forget to set python home with Py_SetPythonHome(). These steps must be sufficient for your code compile and run.

C++ - Create Pythonwrapper to existing Library

I need to write a python wrapper for an existing C++ Module. First I tested the procedere with this basic example (which now actually works fine): C++ - Python Binding with ctypes - Return multiple values in function
Now I tried to change the setting: I want to use the existing lib instead of my single cpp file. I tried it with this:
g++ -c -I. -fPIC projectionWrapper.cpp -o projectionWrapper.o
g++ -shared -Wl,-soname,libproj.so
-L./build/liborig_interface.a,./build/liborig_base.a
-o libproj.so projectionWrapper.o
I wanted to link against both .a files from the given library with the -L command. I don't get any errors on that, but when I try to import the module via ipython, I get this:
import myprojection # I load libproj.so in this python file
OSError: ./libproj.so: undefined symbol: _Z29calibration_loadPKcjbP14camera_typetS2_
There is a function "calibration_load", as well a "camera_type" in the original framework. But I have no clue where the cryptic things in between come from.
Sorry for my vague explanation, I tried to explain it as good as possible, but a C++ Wrapper is not one of my topics where I feel "at home".
The problem is that you're not linking against the external library that you use in your C++ code; add -l<library> to your second g++ call.
g++ -shared projectionWrapper.o
-L./build/base -L./build/interface
-loriginterface -lorigbase
-Wl,-soname,libproj.so
-o libproj.so
did the job. Thanks for the hint that I actually didn't link the libraries as I only used the -L option.
Moreover the order of the options was wrong. I had to state "projectionWrapper.o" right at the beginning, as well as "-loriginterface" before "-lorigbase". This was answered here: "undefined reference" when linking against a static library
(complete name of the libs are: liboriginterface.a and liborigbase.a)

Unable to Install pyslalib package using python2.7 / MINGW on Windows 10

I'm trying to install the pyslalib package using python 2.7 on Windows 10 and keep getting the following:
"collect2.exe: error: ld returned 1 exit status"
message when I try to run "python setup.py install". I think this might be an issue with my mingw configuration, but I can't seem to locate the problem.
Any help with this issue would be greatly appreciated. I've eaten up most of the weekend struggling with this.
Thanks,
The output errors are:
C:\Python27\libs/libpython27.a(dmmes01026.o):(.idata$7+0x0): undefined reference to `_head_C__build27_cpython_PCBuild_libpython27_a'
C:\Python27\libs/libpython27.a(dmmes00281.o):(.idata$7+0x0): undefined reference to `_head_C__build27_cpython_PCBuild_libpython27_a'
C:\Python27\libs/libpython27.a(dmmes00105.o):(.idata$7+0x0): undefined reference to `_head_C__build27_cpython_PCBuild_libpython27_a'
C:\Python27\libs/libpython27.a(dmmes00253.o):(.idata$7+0x0): undefined reference to `_head_C__build27_cpython_PCBuild_libpython27_a'
C:\Python27\libs/libpython27.a(dmmes00227.o):(.idata$7+0x0): undefined reference to `_head_C__build27_cpython_PCBuild_libpython27_a'
C:\Python27\libs/libpython27.a(dmmes00712.o):(.idata$7+0x0): more undefined references to `_head_C__build27_cpython_PCBuild_libpython27_a' follow
collect2.exe: error: ld returned 1 exit status
This looks like a problem I had recently. I think there is a problem with the libpython27.a that comes included with Python (I'm on version 2.7.10). Creating my own libpython27.a from the python27.dll as per the instructions found here fixed the problem.
To create Python extensions, you need to link against the Python
library. Unfortunately, most Python distributions are provided with
Python22.lib, a library in Microsoft Visual C++ format. GCC expects a
.a file (libpython22.a to be precise.). Here's how to convert
python22.lib to libpython22.a:
Download pexport (from here or
https://web.archive.org/web/20000829082204/http://starship.python.net/crew/kernr/mingw32/pexports-0.42h.zip).
Get
Python22.dll (it should be somewhere on your harddrive).
Run :
pexports python22.dll > python22.def This will extract all symbols
from python22.dll and write them into python22.def.
Run : dlltool --dllname python22.dll --def python22.def --output-lib libpython22.a This will create libpython22.a (dlltool is part of MinGW utilities).
Copy libpython22.a to c:\python22\libs\ (in the same directory as
python22.lib).
This trick should work for all Python versions,
including future releases of Python. You can also use this trick to
convert other libraries.

compiling Cython with MinGW - undefined reference PyExc

I'm trying to compile a simple code snippet from the book "Cython - A guide for Python programmers", and when i compile, i get the following error:
H:\Cython>python setup.py build_ext -i --compiler=mingw32
running build_ext
building 'fib' extension
C:\MinGW\bin\gcc.exe -mdll -O -Wall -IC:\Anaconda3\include -IC:\Anaconda3\include -c fib.c -o build\temp.win32-3.4\Release\fib.o
writing build\temp.win32-3.4\Release\fib.def
C:\MinGW\bin\gcc.exe -shared -s build\temp.win32-3.4\Release\fib.o build\temp.win32-3.4\Release\fib.def -LC:\Anaconda3\libs -LC:\Ana
conda3\PCbuild -lpython34 -lmsvcr100 -o H:\Cython\fib.pyd
build\temp.win32-3.4\Release\fib.o:fib.c:(.text+0xb6): undefined reference to `_imp__PyExc_TypeError'
build\temp.win32-3.4\Release\fib.o:fib.c:(.text+0xf3): undefined reference to `_imp__PyExc_TypeError'
build\temp.win32-3.4\Release\fib.o:fib.c:(.text+0x3cc): undefined reference to `_imp___PyThreadState_Current'
build\temp.win32-3.4\Release\fib.o:fib.c:(.text+0x857): undefined reference to `_imp__PyExc_NameError'
build\temp.win32-3.4\Release\fib.o:fib.c:(.text+0xa55): undefined reference to `_imp__PyExc_ImportError'
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: build\temp.win32-3.4\Release\fib.o: bad reloc address 0x0 in s
ection `.data'
collect2.exe: error: ld returned 1 exit status
error: command 'C:\\MinGW\\bin\\gcc.exe' failed with exit status 1
H:\Cython>
setup.py:
from distutils.core import setup
from Cython.Build import cythonize
setup(ext_modules=cythonize('fib.pyx'))
fib.pyx:
def fib(int n):
cdef int i
cdef double a=0.0, b=1.0
for i in range(n):
a, b = a + b, a
return a
When I google this problem, others who have had the error had a mix between 32 and 64 bit stuff, I'm not doing that.
I sat down and looked the errors over again today, and found the issue.
The problem is that I used Anaconda rather than compiling everything from scratch myself - that means that some Cython components were compiled with MSVC. As above you can see that I'm trying to use MinGW to compile the Cython test script. Why mixing compilers like that doesn't work is outside my scope of knowledge, but it doesn't. Compiling my Cython test scripts with MSVC works.
(use Visual Studio C++ 2008/2010 for python 2.x/3.x respectively)
As for the reason that I attempted to use MinGW (against standard recommendation) was that my msiserver service had somehow broken (I'm on an old laptop, so i don't recall the reason), and was hoping to find a quick way out, rather than fixing the msiserver service.
The fix for the msiserver service is pretty unrelated to this question, but it was rather hard to find, so i figured I'd link and mirror it here:
http://www.vistax64.com/vista-installation-setup/96680-repair-windows-installer-service-vista-all-versions.html
For all those unfortunate souls searching and Googling for how to
repair the Windows Installer Service, I have some info for you. A
couple days ago I tried to uninstall one of my apps and stalled on an
error "Windows Installer Service cannot be accessed". After many
trials and errors trying to fix this issue, I stumbled upon a new fix
for this issue that has worked in all these situations where the
Windows Installer Service will not manually start and in essense, not
allow install or uninstall tasks to complete.
Here's the easy steps:
1. Go to a Windows Vista (Any Version) computer that has the Windows
Installer service running correctly and run regedit(Start-Run-Regedit)
2. Go to the location
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\msiserver
3. Right click on this key and select "Export" and save the key to a Flash
Drive or other.
4. Run sfc /scannow on the damaged Vista computer - you won't need the
install disk as it goes to backup files on your HD. Do not reboot when
complete
5. Double click saved .reg file from working machine and import registry
settings into damaged Vista computer.
6. Now reboot and try to install/uninstall
If many of you have success with this method, please post this fix
around the WWW as I went through over 1000 links with users having the
same problem and not being able to solve it. Shame on Microsoft, very
sloppy. It would have been so nice if Microsoft released Windows
Installer 4.0 as a standalone installation with Vista's release so I
could have repaired it, most users have been doing fresh installs to
fix this. Get your act together Microsoft!!!!
The CAT
Thank you, the cat.

communicate between python and C++

I want to create a python module which can have its functions called from a C++ class and call c++ functions from that class
i have looked at boost however it hasn't seemed to make any sense
it refers to a shared library (which i have no idea how to create) and i cant fallow the code they use in examples (it seems very confusing)
here is their hello world tutorial
(http://www.boost.org/doc/libs/1_55_0b1/libs/python/doc/tutorial/doc/html/index.html#python.quickstart)
Following C/C++ tradition, let's start with the "hello, world". A C++ Function:
char const* greet()
{
return "hello, world";
}
can be exposed to Python by writing a Boost.Python wrapper:
include <boost/python.hpp>
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
That's it. We're done. We can now build this as a shared library. The resulting DLL is now
visible to Python. Here's a sample Python session:
>>> import hello_ext
>>> print hello_ext.greet()
hello, world
Next stop... Building your Hello World module from start to finish...
could someone please help explain what is being done and most of all how python knows about the C++ file
Python does not know about the C++ file, it will only be aware of the extension module that is compiled from the C++ file. This extension module is an object file, called a shared library. This file has an interface that looks to Python as if it was a normal Python module.
This object file will only exist after you tell a compiler to compile the C++ file and link it with all the libraries it needs. Of course, the first library needed is Boost.Python itself, which must be available on the system where you are compiling.
You can tell Python to compile the C++ file for you, so that you do not need to mess with the compiler and its library flags. In order to do so, you need a file called setup.py where you use the Setuptools library or the standard Distutils to define how your other Python modules are to be installed on the system. One of the steps for installing is compiling all extension modules, called the build_ext phase.
Let us imagine you have the following directories and files:
hello-world/
├── hello_ext.cpp
└── setup.py
The content of setup.py is:
from distutils.core import setup
from distutils.extension import Extension
hello_ext = Extension(
'hello_ext',
sources=['hello_ext.cpp'],
include_dirs=['/opt/local/include'],
libraries=['boost_python-mt'],
library_dirs=['/opt/local/lib'])
setup(
name='hello-world',
version='0.1',
ext_modules=[hello_ext])
As you can see, we are telling Python there is an Extension we want to compile, where the source file is, and where the included libraries are to be found. This is system-dependent. The example shown here is for a Mac OS X system, where Boost libraries were installed via MacPorts.
The content of hello_ext.cpp is as shown in the tutorial, but take care to reorder things so that the BOOST_PYTHON_MODULE macro comes after the definitions of whatever must be exported to Python:
#include <boost/python.hpp>
char const* greet()
{
return "hello, world";
}
BOOST_PYTHON_MODULE(hello_ext)
{
using namespace boost::python;
def("greet", greet);
}
You can then tell Python to compile and link for you by executing the following on the command line:
$ python setup.py build_ext --inplace
running build_ext
building 'hello_ext' extension
/usr/bin/clang -fno-strict-aliasing -fno-common -dynamic -pipe -Os -fwrapv -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/opt/local/include -I/opt/local/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c hello_ext.cpp -o build/temp.macosx-10.9-x86_64-2.7/hello_ext.o
/usr/bin/clang++ -bundle -undefined dynamic_lookup -L/opt/local/lib -Wl,-headerpad_max_install_names -L/opt/local/lib/db46 build/temp.macosx-10.9-x86_64-2.7/hello_ext.o -L/opt/local/lib -lboost_python-mt -o ./hello_ext.so
(The --inplace flag tells Python to leave the products of compilation right next to the source files. The default is to move them to a build directory, to keep the source directory clean.)
After that, you will find a new file called hello_ext.dll (or hello_ext.so on Unix) on the hello-world directory. If you start a Python interpreter in that directory, you will be able to import the module hello_ext and use the function greet, as shown in the Boost tutorial.
Python is an interpreted language. This means that it needs a virtual machine to execute the statements. For example, if it encounters a = 5, python (or rather the virtual machine that interprets your python code), will create an object in memory that holds some information and the value 5 and will make sure that any following reference to a will find the object. Same goes for more complex statements like input, on these commands, the virtual machine will trigger a hard coded routine which will do a lot of work under the hood before returning back to read the next piece of python code. So far, so good.
About modules. When issuing the import statement, python will look for the specified module name into its path. This is usually a .py file containing only pure python code to interpret. But that can also be a .pyd file, containing compiled routines that python can use like an executable would do with a shared library. This file contains symbols and entry points so that when the interpreter finds a special method name like mymodule.mymethod() it knows where to find the routine to execute and runs it.
However, these routines have to conform to a specific interface, and that's why it is not straightforward to expose C/C++ functions to python. The most obvious problem is that python int is not a C int, not a short, not even a long. It's a special structure that holds a lot more information like how often the variable is referenced (to be able to free memory for variables that are not referenced anymore), the type of the value it holds, etc. Of course, a typical C/C++ library doesn't work with these complex types, but uses vanilla int, float, char* and other nice plain types. So one has to translate the necessary python values to simple C types that can be understood by the library, and convert back the potential results delivered by the library into a format usable by python's virtual machine. This is what is called the wrapper. The wrapper also has to take care of funny things like reference counts, memory management on the heap, initialization and finalization, and other monkeys. See some examples to get an idea of how such code can look like. This is not extremely complicated, but still some work.
Now you get an idea of all the hard work done under the hood by the Python.Boost library (or other wrapping tools for that matters) when calling the ridiculously simple def("greet", greet);.

Categories