[C++-sig] function with void * parameter on MSVC 7, Boost.Python

David Abrahams dave at boost-consulting.com
Sat Apr 19 16:40:51 CEST 2003


"c++-sig" <cplusplus-sig at brewer.com> writes:

> I am trying to wrap a C++ api that makes use of void *'s internally but
> my problem boils down to a very simple example where I get a compiler
> error. The error occurs in a section of Boost.Python code where msvc
> RTTI type info names are undecorated (this code is only compiled into
> MSVC compiler builds). My question can be reduced to what happens if I
> remove this undecoration (which makes my compile work).

I don't think that has anything to do with the actual problem.
Boost.Python simply doesn't convert void* to/from python, and wasn't
designed to.  I tried using Gottfried Gaunsage's opaque pointer
converter stuff to treat void* as an opaque pointer, but it doesn't
work out simply for various uninteresting reasons.

> Ok, now the details:
>
> #include <boost/python.hpp>
> #include <prextl.h>
>
> using namespace boost::python;
>
> void dog(void *x);
>
> BOOST_PYTHON_MODULE(test)
> {
>     def("dog",dog);
> }
>

I suppose it would be good to modify Boost.Python to accomodate void*,
but it will take some work and is not high on my list at the moment
(that could be chaged - funded development gets the highest priority).
In the meantime I suggest you use thin wrappers which cast the void*
to/from some other opaque pointer type, as follows:

    #include <boost/python.hpp>
    #include <prextl.h>

    using namespace boost::python;

    struct void_;
    void dog(void *x);
    inline void dog2(void_* x) { dog(x); }

    BOOST_PYTHON_OPAQUE_SPECIALIZED_TYPE_ID(void_);

    BOOST_PYTHON_MODULE(test)
    {
        def("dog",dog2);
    }

> When I compile using Visual Studio .NET (I am assuming the same problem
> exists on VC++ 6), I get the following error:
> c:\projects\XPython\boost\boost\python\detail\msvc_typeinfo.hpp(45) :
> error C2784: 'boost::python::detail::typeinfo
> boost::python::detail::typeid_ref_1(T &(__stdcall *)(void))' : could not
> deduce template argument for ' &(__stdcall *)(void)' from 'void
> (__stdcall *)(void)'
>
> It appears as though the msvc_typeinfo.hpp file exists for the following
> reason in a comment at the top of the file:
> // Fix for MSVC's broken typeid() implementation which doesn't strip
> // decoration. This fix doesn't handle cv-qualified array types. It
> // could probably be done, but I haven't figured it out yet.
>
> And the template on which it dies looks like this:
> template <class T>
> inline typeinfo msvc_typeid(boost::type<T>* = 0)
> {
>     return detail::typeid_ref(
>         (boost::type<T>*)0, detail::is_ref_tester1(type<T>())
>         );
> }
>
> If I replace the return statement with return typeid(T); things compile
> just fine (this is what happens on other compilers). 

Yes, but you'll still have no way to convert a void* _to_ python, so
you can't wrap any functions that return them.

> But I'm wondering what the effects are of not undecorating the msvc
> type names? 

Lots of bad effects, trust me.  If you really think this workaround is
good enough (I don't see how it could be, since you need to produce a
Python object that can be converted to/from void*), you should do it
with specialization:

    template <>
    inline typeinfo msvc_typeid(boost::type<void>* = 0)
    {
        return typeid(void);
    }

(actually, I suppose I should have that specialization anyway for
completeness).

> Would it mean that if Python were compiled with a
> non-microsoft compiler, automatic type conversion would not work?

No, nothing like that.  Boost.Python simply relies in several places
on the fact that:

   typeid(T) == typeid(T const) == typeid(T const volatile) ==
   typeid(T&) == typeid(T const&) ...

but vc6 and vc7 don't act that way, so msvc_typeinfo takes care of the
problem for us.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list