Using SWIG to build C++ extension

M

mk

Hello,

I'm having terrible problems building C++ extension to Python 2.4 using
SWIG. I'd appreciate if somebody knowledgeable at the subject took a
look at it. swig-1.3.29, g++ (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52).

I used following commands to build C++ extension:

# swig -c++ -python edit_distance.i
# c++ -c edit_distance.c edit_distance_wrap.cxx edit_distance.cpp -I.
-I/usr/include/python2.4


Linux RH (9.156.44.105) root ~/tmp # c++ -c edit_distance.c
edit_distance_wrap.cxx edit_distance.cpp -I. -I/usr/include/python2.4
c++: edit_distance.cpp: No such file or directory
edit_distance_wrap.cxx: In function ‘PyObject*
_wrap_edit_distance(PyObject*, PyObject*)’:
edit_distance_wrap.cxx:2579: error: ‘string’ was not declared in this scope
edit_distance_wrap.cxx:2579: error: ‘arg1’ was not declared in this scope
edit_distance_wrap.cxx:2580: error: ‘arg2’ was not declared in this scope
edit_distance_wrap.cxx:2597: error: expected type-specifier before ‘string’
edit_distance_wrap.cxx:2597: error: expected `>' before ‘string’
edit_distance_wrap.cxx:2597: error: expected `(' before ‘string’
edit_distance_wrap.cxx:2597: error: expected primary-expression before
‘>’ token
edit_distance_wrap.cxx:2597: error: expected `)' before ‘;’ token
edit_distance_wrap.cxx:2605: error: expected type-specifier before ‘string’
edit_distance_wrap.cxx:2605: error: expected `>' before ‘string’
edit_distance_wrap.cxx:2605: error: expected `(' before ‘string’
edit_distance_wrap.cxx:2605: error: expected primary-expression before
‘>’ token
edit_distance_wrap.cxx:2605: error: expected `)' before ‘;’ token

What's weird is that I _did_ use std:: namespace prefix carefully in the
code:

#include <string>
#include <vector>
#include <iostream>

const unsigned int cost_del = 1;
const unsigned int cost_ins = 1;
const unsigned int cost_sub = 1;


unsigned int edit_distance( std::string& s1, std::string& s2 )
{
const size_t len1 = s1.length(), len2 = s2.length();
std::vector<std::vector<unsigned int> > d(len1 + 1,
std::vector<unsigned int>(len2 + 1));

for(int i = 1; i <= len1; ++i)
for(int j = 1; j <= len2; ++j)
d[j] = std::min(d[i - 1][j] + 1,
std::min(d[j - 1] + 1, d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0
: 1)));

return d[len1][len2];
}

Ok, anyway I fixed it in the generated code (edit_distance_wrap.cxx). It
compiled to .o file fine then. It linked to _edit_distance.so as well:

# c++ -shared edit_distance_wrap.o -o _edit_distance.so

But now I get import error in Python!

Linux RH root ~/tmp # python
Python 2.4.3 (#1, Dec 11 2006, 11:38:52)
[GCC 4.1.1 20061130 (Red Hat 4.1.1-43)] on linux2
Type "help", "copyright", "credits" or "license" for more information.Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "edit_distance.py", line 5, in ?
import _edit_distance
ImportError: ./_edit_distance.so: undefined symbol: _Z13edit_distanceRSsS_



What did I do to deserve this? :)


edit_distance.i file just in case:

%module edit_distance
%{
#include "edit_distance.h"
%}

extern unsigned int edit_distance(string& s1, string& s2);
 
B

Bas Michielsen

mk said:
Hello,

I'm having terrible problems building C++ extension to Python 2.4 using
SWIG. I'd appreciate if somebody knowledgeable at the subject took a
look at it. swig-1.3.29, g++ (GCC) 4.1.1 20070105 (Red Hat 4.1.1-52).

I used following commands to build C++ extension:

# swig -c++ -python edit_distance.i
# c++ -c edit_distance.c edit_distance_wrap.cxx edit_distance.cpp -I.
-I/usr/include/python2.4


Linux RH (9.156.44.105) root ~/tmp # c++ -c edit_distance.c
edit_distance_wrap.cxx edit_distance.cpp -I. -I/usr/include/python2.4
c++: edit_distance.cpp: No such file or directory
edit_distance_wrap.cxx: In function ‘PyObject*
_wrap_edit_distance(PyObject*, PyObject*)’:
edit_distance_wrap.cxx:2579: error: ‘string’ was not declared in this
scope edit_distance_wrap.cxx:2579: error: ‘arg1’ was not declared in this
scope edit_distance_wrap.cxx:2580: error: ‘arg2’ was not declared in this
scope edit_distance_wrap.cxx:2597: error: expected type-specifier before
‘string’ edit_distance_wrap.cxx:2597: error: expected `>' before ‘string’
edit_distance_wrap.cxx:2597: error: expected `(' before ‘string’
edit_distance_wrap.cxx:2597: error: expected primary-expression before
‘>’ token
edit_distance_wrap.cxx:2597: error: expected `)' before ‘;’ token
edit_distance_wrap.cxx:2605: error: expected type-specifier before
‘string’ edit_distance_wrap.cxx:2605: error: expected `>' before ‘string’
edit_distance_wrap.cxx:2605: error: expected `(' before ‘string’
edit_distance_wrap.cxx:2605: error: expected primary-expression before
‘>’ token
edit_distance_wrap.cxx:2605: error: expected `)' before ‘;’ token

What's weird is that I _did_ use std:: namespace prefix carefully in the
code:

#include <string>
#include <vector>
#include <iostream>

const unsigned int cost_del = 1;
const unsigned int cost_ins = 1;
const unsigned int cost_sub = 1;


unsigned int edit_distance( std::string& s1, std::string& s2 )
{
const size_t len1 = s1.length(), len2 = s2.length();
std::vector<std::vector<unsigned int> > d(len1 + 1,
std::vector<unsigned int>(len2 + 1));

for(int i = 1; i <= len1; ++i)
for(int j = 1; j <= len2; ++j)
d[j] = std::min(d[i - 1][j] + 1,
std::min(d[j - 1] + 1, d[i - 1][j - 1] + (s1[i - 1] == s2[j - 1] ? 0
: 1)));

return d[len1][len2];
}

Ok, anyway I fixed it in the generated code (edit_distance_wrap.cxx). It
compiled to .o file fine then. It linked to _edit_distance.so as well:

# c++ -shared edit_distance_wrap.o -o _edit_distance.so

But now I get import error in Python!

Linux RH root ~/tmp # python
Python 2.4.3 (#1, Dec 11 2006, 11:38:52)
[GCC 4.1.1 20061130 (Red Hat 4.1.1-43)] on linux2
Type "help", "copyright", "credits" or "license" for more information.Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "edit_distance.py", line 5, in ?
import _edit_distance
ImportError: ./_edit_distance.so: undefined symbol: _Z13edit_distanceRSsS_



What did I do to deserve this? :)


edit_distance.i file just in case:

%module edit_distance
%{
#include "edit_distance.h"
%}

extern unsigned int edit_distance(string& s1, string& s2);


Hello,

I took your example files and did the following:
changed the #include "edit_distance.h" to #include "edit_distance.c"
in the edit_distance.i file.
Then I changed the first few lines of your function definition
unsigned int edit_distance( const char* c1, const char* c2 )
{
std::string s1( c1), s2( c2);
and also adapted the signature in the edit_distance.i file.
Then
swig -shadow -c++ -python edit_distance.i
g++ -c -fpic -I/usr/include/python edit_distance_wrap.cxx
g++ -shared edit_distance_wrap.o -o _edit_distance.so

I could import edit_distance without any error messages1

Perhaps I changed too many things, but this may get you started,

Regards,

Bas
 
M

mk

Hello Bas,

Thanks, man! Your recipe worked on Debian system, though not on RedHat,
and I still have no idea why. :) Anyway, I have it working. Thanks again.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,149
Members
46,695
Latest member
StanleyDri

Latest Threads

Top