49
[me@hostname python]$ cat hello_world.cc
#include <string>
#include <Python.h>
#include <boost/python.hpp>

namespace {
  std::string greet() { return "Helloworld"; }
}

using namespace boost::python;

BOOST_PYTHON_MODULE(hello_world)
{
  def("greet",greet);
}

[me@hostnmae python]$ g++ -c -fPIC hello_world.cc -I/path/to/boost/headers -I/path/to/python/headers -o hello_world.o
[me@hostname python]$ g++ -shared -Wl,-soname,libhello_world.so -o libhello_world.so  hello_world.o
[me@hostname python]$ python
Python 2.7.1 (r271:86832, Jan 10 2011, 09:46:57)
[GCC 3.4.5 20051201 (Red Hat 3.4.5-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.path.append('.')
>>> import hello_world
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named hello_world
>>>

I created the .so file as shown above but I'm not able to import inside python. what am I missing?

2 Answers 2

30

take that 'hello_world.so' file and and make new python file (in the same dir) named as 'hello_world.py'. Put the below code in it.. .

def __bootstrap__():
   global __bootstrap__, __loader__, __file__
   import sys, pkg_resources, imp
   __file__ = pkg_resources.resource_filename(__name__,'hello_world.so')
   __loader__ = None; del __bootstrap__, __loader__
   imp.load_dynamic(__name__,__file__)
__bootstrap__()

now you can import this hello_world as:

>>> import hello_world
Sign up to request clarification or add additional context in comments.

4 Comments

Should "_bootstrap_" be renamed to, say "_bootstrap"? I spent a lot of time trying to find the documentation for it, thinking it was a special reserved word, but I couldn't find anything. From python.org/dev/peps/pep-0008/#naming-conventions: _double_leading_and_trailing_underscore_ : "magic" objects or attributes that live in user-controlled namespaces. E.g. _init_ , _import_ or _file_ . Never invent such names; only use them as documented.
we can copy but can u add some detail about info.How does it work.
I tried this with module readline. I happen to have a python version #1 (2.7.12) installed with apt-get, which has readline, and another version #2 (2.7.11), simply expanded, which does not. So I added a readline.py in one of the directories in sys.path for version #2, and a symlink in the same dir to /usr/lib/python2.7/lib-dynload/readline.x86_64-linux-gnu.so from version #1. I still get the error.
is this the only solution? I don't see this any Cython documentation so it feels like a workaround.
29

It must be called hello_world.so, not libhello_world.so.

5 Comments

thanks. Now I get ImportError: ./hello_world.so: undefined symbol: _ZNK12boost_1_47_06python7objects21py_function_impl_base9max_arityEv
@balki: You didn't link with Boost.Python.
I linked against boost_python, Now I get ImportError: libboost_python: cannot open shared object file: No such file or directory. If I export LD_LIBRARY_PATH=/path/to/boost_python_lib, it works fine. How do I specify in cmdline?
LD_LIBRARY_PATH=/path/to/boost_python_lib python would be straightforward. I'd suggest you symlink boost_python_lib to /usr/local/lib if you can, then you get it hassle-free. You can also hardcode the path in the .so file by passing -Wl,-rpath=/path/to/boost_python_lib to the compiler (which is actually processed by the linker).
You are my hero. Fixing that with a symlink, so it won't become stale every time I recompile it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.