Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Wrapping C++ code for python using SWIG. Can't use cout command

I'm trying to wrap for python this simple C++ code using SWIG:

#include "hello.h"

int helloW() 
{
    std::cout << "Hello, World!" ;
    return 0;
}

and here the relative header:

#include <iostream>
int helloW() ; // decl

As SWIG input file I'm using:

/* file : pyhello.i */

/* name of module to use*/
%module pyhello
%{
    #include "hello.h"
%}    
%include "hello.h";

Now, my makefile (which is running fine) is:

all:
    swig -c++ -python -Wall pyhello.i 
    gcc -c -fpic pyhello_wrap.cxx hello.cpp -I/usr/include/python2.7
    gcc -shared hello.o pyhello_wrap.o -o _pyhello.so

as I was able to put together from different sources relative to the problem online. Now, once I try to import in python my library as done with the command

>>> import pyhello

This is the error I get:

    Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "pyhello.py", line 17, in <module>
    _pyhello = swig_import_helper()
  File "pyhello.py", line 16, in swig_import_helper
    return importlib.import_module('_pyhello')
  File "/usr/lib/python2.7/importlib/__init__.py", line 37, in import_module
    __import__(name)
ImportError: ./_pyhello.so: undefined symbol: _ZSt4cout

Which makes me thing this issue is something relative to the command std::cout or, in general, to the standard library <iostream>.

Hope someone can give me some tips regarding this problem. Thanks so much in advance!!

NOTE: same kind of issue I get trying to use the command printf() instead of std::cout and the library <cstdio> instead of <iostream>

like image 598
Rocco B. Avatar asked Jan 15 '18 18:01

Rocco B.


1 Answers

ImportError: ./_pyhello.so: undefined symbol: _ZSt4cout

with c++filt _ZSt4cout you'll find out that it is std::cout (name mangling).

You should use g++, not gcc, notably in your linker command (with -shared).

Or you need to link explicitly with some -lstdc++ your shared library.

Read Drepper's How to Write Shared Libraries (since Python is dlopen(3)-ing then dlsym(3)-ing it).

You'll better declare as extern "C" int helloW(void); your routine (read C++ dlopen minihowto).

like image 168
Basile Starynkevitch Avatar answered Oct 14 '22 13:10

Basile Starynkevitch