By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,985 Members | 1,574 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,985 IT Pros & Developers. It's quick & easy.

C Function Pointer Wrapping Example not working

P: n/a
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_opiiPFiiiE

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

%callback("%s_cb");
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
Nov 14 '08 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Charlie <Ch*************@gmail.comwrote:
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_opiiPFiiiE
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 <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Nov 16 '08 #2

P: n/a
>
*But when I try to import test in python, it complains:
*import _test
*ImportError: ./_test.so undefined symbol: _Z9binary_opiiPFiiiE

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_opiiPFiiiE" 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_cb");
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
---------------------------------
Nov 17 '08 #3

P: n/a
On Nov 16, 8:56*pm, Charlie <Charlie.Xia....@gmail.comwrote:
*But when I try to import test in python, it complains:
*import _test
*ImportError: ./_test.so undefined symbol: _Z9binary_opiiPFiiiE
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_opiiPFiiiE" 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 overcomplicating. 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?
Nov 17 '08 #4

P: n/a
Charlie <Ch*************@gmail.comwrote:
>
?But when I try to import test in python, it complains:
?import _test
?ImportError: ./_test.so undefined symbol: _Z9binary_opiiPFiiiE
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_opiiPFiiiE" 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_cb");
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 <ni**@craig-wood.com-- http://www.craig-wood.com/nick
Nov 17 '08 #5

P: n/a
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
Nov 18 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.