Using SWIG to build C++ extension

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • mk

    Using SWIG to build C++ extension

    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_w rap.cxx edit_distance.c pp -I.
    -I/usr/include/python2.4


    Linux RH (9.156.44.105) root ~/tmp # c++ -c edit_distance.c
    edit_distance_w rap.cxx edit_distance.c pp -I. -I/usr/include/python2.4
    c++: edit_distance.c pp: No such file or directory
    edit_distance_w rap.cxx: In function ‘PyObject*
    _wrap_edit_dist ance(PyObject*, PyObject*)’:
    edit_distance_w rap.cxx:2579: error: ‘string’ was not declared in this scope
    edit_distance_w rap.cxx:2579: error: ‘arg1’ was not declared in this scope
    edit_distance_w rap.cxx:2580: error: ‘arg2’ was not declared in this scope
    edit_distance_w rap.cxx:2597: error: expected type-specifier before ‘string’
    edit_distance_w rap.cxx:2597: error: expected `>' before ‘string’
    edit_distance_w rap.cxx:2597: error: expected `(' before ‘string’
    edit_distance_w rap.cxx:2597: error: expected primary-expression before
    ‘>’ token
    edit_distance_w rap.cxx:2597: error: expected `)' before ‘;’ token
    edit_distance_w rap.cxx:2605: error: expected type-specifier before ‘string’
    edit_distance_w rap.cxx:2605: error: expected `>' before ‘string’
    edit_distance_w rap.cxx:2605: error: expected `(' before ‘string’
    edit_distance_w rap.cxx:2605: error: expected primary-expression before
    ‘>’ token
    edit_distance_w rap.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<unsign ed int d(len1 + 1,
    std::vector<uns igned int>(len2 + 1));

    for(int i = 1; i <= len1; ++i)
    for(int j = 1; j <= len2; ++j)
    d[i][j] = std::min(d[i - 1][j] + 1,
    std::min(d[i][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_w rap.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.
    >>import edit_distance
    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_distan ceRSsS_



    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(s tring& s1, string& s2);





  • Bas Michielsen

    #2
    Re: Using SWIG to build C++ extension

    mk wrote:
    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_w rap.cxx edit_distance.c pp -I.
    -I/usr/include/python2.4
    >
    >
    Linux RH (9.156.44.105) root ~/tmp # c++ -c edit_distance.c
    edit_distance_w rap.cxx edit_distance.c pp -I. -I/usr/include/python2.4
    c++: edit_distance.c pp: No such file or directory
    edit_distance_w rap.cxx: In function ‘PyObject*
    _wrap_edit_dist ance(PyObject*, PyObject*)’:
    edit_distance_w rap.cxx:2579: error: ‘string’ was not declared in this
    scope edit_distance_w rap.cxx:2579: error: ‘arg1’ was not declared in this
    scope edit_distance_w rap.cxx:2580: error: ‘arg2’ was not declared in this
    scope edit_distance_w rap.cxx:2597: error: expected type-specifier before
    ‘string’ edit_distance_w rap.cxx:2597: error: expected `>' before ‘string’
    edit_distance_w rap.cxx:2597: error: expected `(' before ‘string’
    edit_distance_w rap.cxx:2597: error: expected primary-expression before
    ‘>’ token
    edit_distance_w rap.cxx:2597: error: expected `)' before ‘;’ token
    edit_distance_w rap.cxx:2605: error: expected type-specifier before
    ‘string’ edit_distance_w rap.cxx:2605: error: expected `>' before ‘string’
    edit_distance_w rap.cxx:2605: error: expected `(' before ‘string’
    edit_distance_w rap.cxx:2605: error: expected primary-expression before
    ‘>’ token
    edit_distance_w rap.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<unsign ed int d(len1 + 1,
    std::vector<uns igned int>(len2 + 1));
    >
    for(int i = 1; i <= len1; ++i)
    for(int j = 1; j <= len2; ++j)
    d[i][j] = std::min(d[i - 1][j] + 1,
    std::min(d[i][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_w rap.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.
    >>import edit_distance
    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_distan ceRSsS_
    >
    >
    >
    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(s tring& 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_w rap.cxx
    g++ -shared edit_distance_w rap.o -o _edit_distance. so

    I could import edit_distance without any error messages
    >>import edit_distance
    >>print edit_distance.e dit_distance( "toto", "titi")
    2
    >>print edit_distance.e dit_distance( "toto", "toti")
    1

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

    Regards,

    Bas

    Comment

    • mk

      #3
      Re: Using SWIG to build C++ extension

      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.

      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_w rap.cxx
      g++ -shared edit_distance_w rap.o -o _edit_distance. so

      Comment

      Working...