Wrapping boost::bind() with Cython

174 views
Skip to first unread message

bruno.l...@gmail.com

unread,
Aug 22, 2016, 1:56:25 PM8/22/16
to cython-users
Hi all,

I am in the process of wrapping a large & complex C++ library with Cython: http://pointclouds.org

It has been easier than I thought until now (so thank you very much to the Cython devteam) but I met some problems with a piece of code which requires me to wrap boost::bind()...

So I have created a minimal test code which mimic the original code:
  • lets say bind.h and bind.cpp is the code of the library I am trying to wrap. You can build with the following command:

$ clang++ -std=c++11 -Wall -pedantic -I<PATH TO BOOST INCLUDES> bind.cpp -o bind


(g++ should work too !)

And hopefully it should work :

$ ./bind

(void*)argv: 0x7fff594f1b30

Hello from some_callback !

some_ptr: 0x7fff594f1b30

End of execution...


You can build a shared lib with this command:

$ clang++ -std=c++11 -Wall -pedantic -shared -I<PATH TO BOOST INCLUDES> bind.cpp -o libbind.so

  • I wrote a Cython wrapper which almost compiles. See _bind_defs.pxd and _bind.pyx. This can be build with a setup.py like this:
from distutils.core import setup, Extension
from Cython.Build import cythonize

ext = Extension("_bind",
                sources=["_bind.pyx"],
                include_dirs=["<PATH TO BOOST INCLUDES>"],
                libraries=["bind"],
                library_dirs=["<PATH TO libbind.so>"],
                language="c++")
setup(name="_bind", ext_modules=cythonize(ext))

I build with the usual command:

$ python setup.py build_ext



But I got 2 errors:
  • The first one:

_bind.cpp:763:17: error: elaborated type refers to a template

  struct boost::arg __pyx_v__1;

                ^

/Users/bu2/.brew/include/boost/bind/arg.hpp:29:26: note: declared here

template< int I > struct arg

                         ^

1 error generated.


(please don't shout at me)
I did not find a better way than to fix the generated code manually, replacing boost::arg by boost::arg<1> (see boost/bind/placesholders.hpp and boost/bind/arg.hpp, it seems to me that Cython can not wrap code such as: template<int i> class arg {} ).

  • The second one:

_bind.cpp:776:22: error: call to 'bind' is ambiguous

  __pyx_v_callback = boost::bind<__pyx_t_10_bind_defs_callback_t>(__pyx_f_5_bind_some_callback, __pyx_v__1);

                     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

/Users/bu2/.brew/include/boost/bind/bind.hpp:1811:5: note: candidate function [with R = void (void *), F = void (*)(void *), A1 = boost::arg<1>]

    BOOST_BIND(F f, A1 a1)

    ^

/Users/bu2/.brew/include/boost/bind/bind.hpp:1796:20: note: expanded from macro 'BOOST_BIND'

#define BOOST_BIND bind

                   ^

/Users/bu2/.brew/include/boost/bind/bind.hpp:1977:5: note: candidate function [with F = void (void *), A1 = boost::arg<1>]

    BOOST_BIND(F f, A1 a1)

    ^

/Users/bu2/.brew/include/boost/bind/bind.hpp:1796:20: note: expanded from macro 'BOOST_BIND'

#define BOOST_BIND bind

                   ^

1 error generated.


Once again, I can fix it manually by replacing boost::bind<__pyx_t_10_bind_defs_callback_t> by boost::bind. In my wrapper code I had to introduce the T template parameter but I could not find the C++ trick (in boost/bind implementation) that allows us to call boost::bind() without specifying template parameters...

Then it builds successfully.

I hope there is a better way to handle those 2 cases but I have been searching for days without luck. Otherwise sed will do it :-)

Best Regards,

Bruno Le Hyaric.




bind.h
bind.cpp
_bind_defs.pxd
_bind.pyx

afdel...@berkeley.edu

unread,
Jun 6, 2018, 12:28:11 AM6/6/18
to cython-users
Hi Bruno, 

I am currently trying to wrap the bind::multi_array function in cython and was hoping you could offer some help.

Andrew
Reply all
Reply to author
Forward
0 new messages