C Function Pointer Wrapping Example not working

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

    C Function Pointer Wrapping Example not working

    Hi All,

    I am new to using swig/C++/python. I got some problem with function
    pointers. I posted in swig-user, but got no response. So I forwarded
    it here. You help is greatly appreciated.

    Thanks!

    ---------- Forwarded message ----------

    Hi All,

    Yesterday I posted about the question I had of template function. This
    time I worked step step from examples in Doc 1.3 to reach my ultimate
    goal. But as I worked on the Function Pointer Example in 5.4.9 in Doc
    1.3, it doesn't work. My platform is a Ubuntu linux with swig 1.3.36,
    python 2.5.2 and gcc 4.2.3.

    The compiling and linking has no errors:

    swig -python -c++ -o test_wrap.cpp test.i
    python setup-test.py build
    running build
    running build_py
    copying test.py -build/lib.linux-i686-2.5
    running build_ext
    building '_test' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -
    Wstrict-prototypes -fPIC -I/usr/include/python2.5 -c test_wrap.cpp -o
    build/temp.linux-i686-2.5/test_wrap.o
    cc1plus: warning: command line option "-Wstrict-prototypes" is valid
    for Ada/C/ObjC but not for C++
    g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-
    i686-2.5/test_wrap.o build/temp.linux-i686-2.5/test.o -o build/
    lib.linux-i686-2.5/_test.so

    But when I try to import test in python, it complains:
    import _test
    ImportError: ./_test.so undefined symbol: _Z9binary_opiiP FiiiE

    My test.i is:
    %module test
    %{
    #include "test.h"
    %}
    %include "test.h"

    %callback("%s_c b");
    int add( int, int ); //add_cb
    int sub( int, int ); //sub_cb
    int mul( int, int ); //mul_cb
    %nocallback;

    My test.h is:

    int binary_op(int a, int b, int (*op)(int,int) );
    int add( int a, int b ) { return a+b; }
    int sub( int a, int b ) { return a-b; }
    int mul( int a, int b ) { return a*b; }
    // NOTE: this is func ptr from example in Doc 1.3: 5.4.9

    It is really strange to me. I am a novice swigger but I really need
    its power to accelerate my development. Could anybody point out where
    my problem is?

    TIA

    Charlie
  • Nick Craig-Wood

    #2
    Re: C Function Pointer Wrapping Example not working

    Charlie <Charlie.Xia.FD U@gmail.comwrot e:
    I am new to using swig/C++/python. I got some problem with function
    pointers. I posted in swig-user, but got no response. So I forwarded
    it here. You help is greatly appreciated.
    >
    Thanks!
    >
    >
    Hi All,
    >
    Yesterday I posted about the question I had of template function. This
    time I worked step step from examples in Doc 1.3 to reach my ultimate
    goal. But as I worked on the Function Pointer Example in 5.4.9 in Doc
    1.3, it doesn't work. My platform is a Ubuntu linux with swig 1.3.36,
    python 2.5.2 and gcc 4.2.3.
    >
    The compiling and linking has no errors:
    >
    swig -python -c++ -o test_wrap.cpp test.i
    python setup-test.py build
    running build
    running build_py
    copying test.py -build/lib.linux-i686-2.5
    running build_ext
    building '_test' extension
    gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -
    Wstrict-prototypes -fPIC -I/usr/include/python2.5 -c test_wrap.cpp -o
    build/temp.linux-i686-2.5/test_wrap.o
    cc1plus: warning: command line option "-Wstrict-prototypes" is valid
    for Ada/C/ObjC but not for C++
    g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-
    i686-2.5/test_wrap.o build/temp.linux-i686-2.5/test.o -o build/
    lib.linux-i686-2.5/_test.so
    >
    But when I try to import test in python, it complains:
    import _test
    ImportError: ./_test.so undefined symbol: _Z9binary_opiiP FiiiE
    The above is a mangled name so you've got some C vs C++ problems I'd
    say.

    You could try putting some extern "C" {} in around all the functions
    which are imported and exported. Have a look at the code SWIG
    generates and see if it puts some extern "C" in and match what it
    does in your code.

    We used to use SWIG in for python embedding in our C++ project, but we
    found that using ctypes is a lot easier. You just write C .so/.dll
    and use ctypes to access them. You can do callbacks and embedding
    python like this too.

    --
    Nick Craig-Wood <nick@craig-wood.com-- http://www.craig-wood.com/nick

    Comment

    • Charlie

      #3
      Re: C Function Pointer Wrapping Example not working

      >
       But when I try to import test in python, it complains:
       import _test
       ImportError: ./_test.so undefined symbol: _Z9binary_opiiP FiiiE
      >
      The above is a mangled name so you've got some C vs C++ problems I'd
      say.
      >
      You could try putting some extern "C" {} in around all the functions
      which are imported and exported.  Have a look at the code SWIG
      generates and see if it puts some extern "C" in and match what it
      does in your code.
      >
      We used to use SWIG in for python embedding in our C++ project, but we
      found that using ctypes is a lot easier.  You just write C .so/.dll
      and use ctypes to access them.  You can do callbacks and embedding
      python like this too.
      Thanks Nick.

      I tried your method, if I am right(please see the attached details),
      and I still got the undefined symbol error like previous. The only
      difference is "_Z9binary_opii PFiiiE" changed to "binary_op" . Could you
      help me more on this. It seems to have a mixed problems here and I
      guess what you've pointed out is one of them. But really, what I do
      now is just try to reproduce the example, how can this fails? What my
      ultimate need is wrapping up a template function taking template
      function pointer as argument. Did you ever try that? Many thanks
      already anyway.

      FILE and ERROR details:

      ---------test.i--------------
      %module test
      %{
      #include "test.h"
      %}
      %include "test.h"

      %callback("%s_c b");
      int myadd( int, int ); //myadd_cb
      int mysub( int, int ); //mysub_cb
      int mymul( int, int ); //mymul_cb
      %nocallback;
      --------------------------------

      -----------test.h--------------
      extern "C"{
      int binary_op(int a, int b, int (*op)(int,int) );
      int myadd( int a, int b ) { return a+b; };
      int mysub( int a, int b ) { return a-b; };
      int mymul( int a, int b ) { return a*b; };
      }
      ---------------------------------

      ------error message----------
      Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "test.py", line 7, in <module>
      import _test
      ImportError: ./_test.so: undefined symbol: binary_op
      ----------------------------------

      -------compiling message-----
      swig -v -python -c++ -o test_wrap.cpp test.i
      LangSubDir: python
      Search paths:
      ./
      ./swig_lib/python/
      /usr/local/share/swig/1.3.36/python/
      ./swig_lib/
      /usr/local/share/swig/1.3.36/
      Preprocessing.. .
      Starting language-specific parse...
      Processing types...
      C++ analysis...
      Generating wrappers...
      python setup-test.py build
      running build
      running build_py
      copying test.py -build/lib.linux-i686-2.5
      running build_ext
      building '_test' extension
      gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -
      Wstrict-prototypes -fPIC -I/usr/include/python2.5 -c test_wrap.cpp -o
      build/temp.linux-i686-2.5/test_wrap.o
      cc1plus: warning: command line option "-Wstrict-prototypes" is valid
      for Ada/C/ObjC but not for C++
      g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-
      i686-2.5/test_wrap.o build/temp.linux-i686-2.5/test.o -o build/
      lib.linux-i686-2.5/_test.so
      ---------------------------------

      Comment

      • Aaron Brady

        #4
        Re: C Function Pointer Wrapping Example not working

        On Nov 16, 8:56 pm, Charlie <Charlie.Xia... .@gmail.comwrot e:
         But when I try to import test in python, it complains:
         import _test
         ImportError: ./_test.so undefined symbol: _Z9binary_opiiP FiiiE
        >
        The above is a mangled name so you've got some C vs C++ problems I'd
        say.
        >
        You could try putting some extern "C" {} in around all the functions
        which are imported and exported.  Have a look at the code SWIG
        generates and see if it puts some extern "C" in and match what it
        does in your code.
        >
        We used to use SWIG in for python embedding in our C++ project, but we
        found that using ctypes is a lot easier.  You just write C .so/.dll
        and use ctypes to access them.  You can do callbacks and embedding
        python like this too.
        >
        Thanks Nick.
        >
        I tried your method, if I am right(please see the attached details),
        and I still got the undefined symbol error like previous. The only
        difference is "_Z9binary_opii PFiiiE" changed to "binary_op" . Could you
        help me more on this. It seems to have a mixed problems here and I
        guess what you've pointed out is one of them. But really, what I do
        now is just try to reproduce the example, how can this fails? What my
        ultimate need is wrapping up a template function taking template
        function pointer as argument. Did you ever try that? Many thanks
        already anyway.
        ------error message----------
        Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          File "test.py", line 7, in <module>
            import _test
        ImportError: ./_test.so: undefined symbol: binary_op
        ----------------------------------
        Hi Charlie,

        I think you're overcomplicatin g. Here's what I think what you want:
        (Unproduced.)
        >>binary_op( 3, 4, myadd )
        7
        >>binary_op( 3, 4, mysub )
        -1
        >>binary_op( 3, 4, mymul )
        12

        Correct?

        Comment

        • Nick Craig-Wood

          #5
          Re: C Function Pointer Wrapping Example not working

          Charlie <Charlie.Xia.FD U@gmail.comwrot e:
          >
          ?But when I try to import test in python, it complains:
          ?import _test
          ?ImportError: ./_test.so undefined symbol: _Z9binary_opiiP FiiiE
          The above is a mangled name so you've got some C vs C++ problems I'd
          say.

          You could try putting some extern "C" {} in around all the functions
          which are imported and exported. ?Have a look at the code SWIG
          generates and see if it puts some extern "C" in and match what it
          does in your code.

          We used to use SWIG in for python embedding in our C++ project, but we
          found that using ctypes is a lot easier. ?You just write C .so/.dll
          and use ctypes to access them. ?You can do callbacks and embedding
          python like this too.
          >
          Thanks Nick.
          >
          I tried your method, if I am right(please see the attached details),
          and I still got the undefined symbol error like previous. The only
          difference is "_Z9binary_opii PFiiiE" changed to "binary_op" . Could you
          help me more on this. It seems to have a mixed problems here and I
          guess what you've pointed out is one of them. But really, what I do
          now is just try to reproduce the example, how can this fails? What my
          ultimate need is wrapping up a template function taking template
          function pointer as argument. Did you ever try that? Many thanks
          already anyway.
          >
          FILE and ERROR details:
          >
          %module test
          %{
          #include "test.h"
          %}
          %include "test.h"
          >
          %callback("%s_c b");
          int myadd( int, int ); //myadd_cb
          int mysub( int, int ); //mysub_cb
          int mymul( int, int ); //mymul_cb
          %nocallback;
          >
          extern "C"{
          int binary_op(int a, int b, int (*op)(int,int) );
          int myadd( int a, int b ) { return a+b; };
          int mysub( int a, int b ) { return a-b; };
          int mymul( int a, int b ) { return a*b; };
          }
          >
          Traceback (most recent call last):
          File "<stdin>", line 1, in <module>
          File "test.py", line 7, in <module>
          import _test
          ImportError: ./_test.so: undefined symbol: binary_op
          Nowhere in your code is the definition of binary_op - that is why you
          get a linker error.

          Is it defined in another C file? If so you need to link it with the
          swig wrapper before you make the .so

          --
          Nick Craig-Wood <nick@craig-wood.com-- http://www.craig-wood.com/nick

          Comment

          • Charlie

            #6
            Re: C Function Pointer Wrapping Example not working

            Nowhere in your code is the definition of binary_op - that is why you
            get a linker error.
            >
            Is it defined in another C file?  If so you need to link it with the
            swig wrapper before you make the .so
            >
            Thanks for pointing out. I sorted the code out finally!

            Charlie

            Comment

            Working...