Wrapping and Passing HWND with Boost.Python

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Wrapping and Passing HWND with Boost.Python

Ehsan Pi
Hello,

I've created a Boost.Python wrapper (using Py++) for a C++ legacy class that takes a HWND window handle in its constructor. However, after exporting the module to python when I try to use it, I get a type mismatch error.
    
--------------------------
Here is the C++ class I'm wrapping: 

    // File Foo.hpp
    //
    #include "Windows.h"
    class Foo
    {
    public:
        Foo( const HWND window ){}

        virtual ~Foo(){}

        virtual int Bar( int num ) { return num; }
    };   
    
--------------------------
The Py++ output:

    INFO Parsing source file "foo.hpp" ...
    INFO gccxml cmd: ""c:\Program Files (x86)\gccxml 0.9\bin\gccxml.exe"  -I"." "foo.hpp" -fxml="d:\temp\tmpdng3ts.xml""
    INFO GCCXML version - 0.9( 1.127 )

    INFO: file "generated_wrapper.cpp" - updated( 0.001607 seconds )
    
--------------------------
The generated wrapper:

    #include "boost/python.hpp"
    
    #include "foo.hpp"

    namespace bp = boost::python;

    struct Foo_wrapper : Foo, bp::wrapper< Foo > {

        Foo_wrapper(::HWND const window )
        : Foo( window )
          , bp::wrapper< Foo >(){
            // constructor
        
        }

        virtual int Bar( int num ) {
            if( bp::override func_Bar = this->get_override( "Bar" ) )
                return func_Bar( num );
            else{
                return this->Foo::Bar( num );
            }
        }
        
        int default_Bar( int num ) {
            return Foo::Bar( num );
        }

    };

    BOOST_PYTHON_MODULE(MyWrapper){
        { //::Foo
            typedef bp::class_< Foo_wrapper > Foo_exposer_t;
            Foo_exposer_t Foo_exposer = Foo_exposer_t( "Foo", bp::init< HWND__ *>(( bp::arg("window") )) );
            bp::scope Foo_scope( Foo_exposer );
            bp::implicitly_convertible< const HWND, Foo >();
            { //::Foo::Bar
            
                typedef int ( ::Foo::*Bar_function_type )( int ) ;
                typedef int ( Foo_wrapper::*default_Bar_function_type )( int ) ;
                
                Foo_exposer.def( 
                    "Bar"
                    , Bar_function_type(&::Foo::Bar)
                    , default_Bar_function_type(&Foo_wrapper::default_Bar)
                    , ( bp::arg("num") ) );
            
            }
        }
    }
    
--------------------------
In python I get the not-match error:

    >>> import MyWrapper
    >>> import win32gui
    >>> hwnd = win32gui.GetDesktopWindow()
    >>> foo = MyWrapper.Foo(hwnd)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    Boost.Python.ArgumentError: Python argument types in
        Foo.__init__(Foo, int)
    did not match C++ signature:
        __init__(struct _object *, struct HWND__ * window)
    >>>

How can I correct this problem to be able to pass a window's handle (from win32gui) in Python to C++ class, and interact with it?

Environment:
Visual Studio 2008, Boost 1.44, gcc-xml 0.9.0, py++ 1.0.0, pygccxml 1.1.0

_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Wrapping and Passing HWND with Boost.Python

Roman Yakovenko
On Mon, Apr 30, 2012 at 9:11 PM, Ehsan Pi <[hidden email]> wrote:

> In python I get the not-match error:
>
>     >>> import MyWrapper
>     >>> import win32gui
>     >>> hwnd = win32gui.GetDesktopWindow()
>     >>> foo = MyWrapper.Foo(hwnd)
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>     Boost.Python.ArgumentError: Python argument types in
>         Foo.__init__(Foo, int)
>     did not match C++ signature:
>         __init__(struct _object *, struct HWND__ * window)
>     >>>
>
> How can I correct this problem to be able to pass a window's handle (from
> win32gui) in Python to C++ class, and interact with it?

I think the error is pretty clear: the exported constructor expects a
pointer to some struct(?) HWND__, while, win32gui returns the handle
as integer. You will have to find some way to associate handle as
integer with handle as HWND__.  Once you find it, you can use
"make_constructor" functionality, which is also supported by py++.

HTH.
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Wrapping and Passing HWND with Boost.Python

Ehsan Pi
Thanks Roman for your quick reply,

That's what confuses me. HWND is essentially a pointer to an int to hold the window handle. How can to convert them to each other?

Ehsan

On Mon, Apr 30, 2012 at 2:46 PM, Roman Yakovenko <[hidden email]> wrote:
On Mon, Apr 30, 2012 at 9:11 PM, Ehsan Pi <[hidden email]> wrote:
> In python I get the not-match error:
>
>     >>> import MyWrapper
>     >>> import win32gui
>     >>> hwnd = win32gui.GetDesktopWindow()
>     >>> foo = MyWrapper.Foo(hwnd)
>     Traceback (most recent call last):
>       File "<stdin>", line 1, in <module>
>     Boost.Python.ArgumentError: Python argument types in
>         Foo.__init__(Foo, int)
>     did not match C++ signature:
>         __init__(struct _object *, struct HWND__ * window)
>     >>>
>
> How can I correct this problem to be able to pass a window's handle (from
> win32gui) in Python to C++ class, and interact with it?

I think the error is pretty clear: the exported constructor expects a
pointer to some struct(?) HWND__, while, win32gui returns the handle
as integer. You will have to find some way to associate handle as
integer with handle as HWND__.  Once you find it, you can use
"make_constructor" functionality, which is also supported by py++.

HTH.
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig


_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Wrapping and Passing HWND with Boost.Python

Roman Yakovenko
On Mon, Apr 30, 2012 at 9:54 PM, Ehsan Pi <[hidden email]> wrote:
> Thanks Roman for your quick reply,
>
> That's what confuses me. HWND is essentially a pointer to an int to hold the
> window handle. How can to convert them to each other?

I am not sure that you are right, but in case you are, use
make_constructor and reinterpret_cast.

Regards,
Roman
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Wrapping and Passing HWND with Boost.Python

Niall Douglas
In reply to this post by Ehsan Pi
A HWND is always a void * i.e. an opaque pointer. Unfortunately some
people using BPL think that BPL can't handle opaque pointers, so they
do fun stuff like use a thunk struct type for void * instead, and
wrap the lot in manual pointer casting. It's far easier just to
declare it an opaque pointer and be done with it.

It is very unfortunate indeed that win32gui returns a HWND as an
integer. It isn't an integer and must not be treated as one. Still,
it's easy to write a routine which converts python integers to void
*.

Niall


On 30 Apr 2012 at 14:54, Ehsan Pi wrote:

> Thanks Roman for your quick reply,
>
> That's what confuses me. HWND is essentially a pointer to an int to hold
> the window handle. How can to convert them to each other?
>
> Ehsan
>
> On Mon, Apr 30, 2012 at 2:46 PM, Roman Yakovenko
> <[hidden email]>wrote:
>
> > On Mon, Apr 30, 2012 at 9:11 PM, Ehsan Pi <[hidden email]> wrote:
> > > In python I get the not-match error:
> > >
> > >     >>> import MyWrapper
> > >     >>> import win32gui
> > >     >>> hwnd = win32gui.GetDesktopWindow()
> > >     >>> foo = MyWrapper.Foo(hwnd)
> > >     Traceback (most recent call last):
> > >       File "<stdin>", line 1, in <module>
> > >     Boost.Python.ArgumentError: Python argument types in
> > >         Foo.__init__(Foo, int)
> > >     did not match C++ signature:
> > >         __init__(struct _object *, struct HWND__ * window)
> > >     >>>
> > >
> > > How can I correct this problem to be able to pass a window's handle (from
> > > win32gui) in Python to C++ class, and interact with it?
> >
> > I think the error is pretty clear: the exported constructor expects a
> > pointer to some struct(?) HWND__, while, win32gui returns the handle
> > as integer. You will have to find some way to associate handle as
> > integer with handle as HWND__.  Once you find it, you can use
> > "make_constructor" functionality, which is also supported by py++.
> >
> > HTH.
> > _______________________________________________
> > Cplusplus-sig mailing list
> > [hidden email]
> > http://mail.python.org/mailman/listinfo/cplusplus-sig
> >
>


--
Technology & Consulting Services - ned Productions Limited.
http://www.nedproductions.biz/. VAT reg: IE 9708311Q.
Work Portfolio: http://careers.stackoverflow.com/nialldouglas/



_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Wrapping and Passing HWND with Boost.Python

Ehsan Pi
Thanks Niall for your response and correction on HWND. 
I'm new to Python (and Boost.Python for that matter) and thought Python was not typed. If not, how can one convert Python integers to void*? Googled but didn't find an answer.

Regards,
Ehsan


On Tue, May 1, 2012 at 9:18 AM, Niall Douglas <[hidden email]> wrote:
A HWND is always a void * i.e. an opaque pointer. Unfortunately some
people using BPL think that BPL can't handle opaque pointers, so they
do fun stuff like use a thunk struct type for void * instead, and
wrap the lot in manual pointer casting. It's far easier just to
declare it an opaque pointer and be done with it.

It is very unfortunate indeed that win32gui returns a HWND as an
integer. It isn't an integer and must not be treated as one. Still,
it's easy to write a routine which converts python integers to void
*.

Niall


On 30 Apr 2012 at 14:54, Ehsan Pi wrote:

> Thanks Roman for your quick reply,
>
> That's what confuses me. HWND is essentially a pointer to an int to hold
> the window handle. How can to convert them to each other?
>
> Ehsan
>
> On Mon, Apr 30, 2012 at 2:46 PM, Roman Yakovenko
> <[hidden email]>wrote:
>
> > On Mon, Apr 30, 2012 at 9:11 PM, Ehsan Pi <[hidden email]> wrote:
> > > In python I get the not-match error:
> > >
> > >     >>> import MyWrapper
> > >     >>> import win32gui
> > >     >>> hwnd = win32gui.GetDesktopWindow()
> > >     >>> foo = MyWrapper.Foo(hwnd)
> > >     Traceback (most recent call last):
> > >       File "<stdin>", line 1, in <module>
> > >     Boost.Python.ArgumentError: Python argument types in
> > >         Foo.__init__(Foo, int)
> > >     did not match C++ signature:
> > >         __init__(struct _object *, struct HWND__ * window)
> > >     >>>
> > >
> > > How can I correct this problem to be able to pass a window's handle (from
> > > win32gui) in Python to C++ class, and interact with it?
> >
> > I think the error is pretty clear: the exported constructor expects a
> > pointer to some struct(?) HWND__, while, win32gui returns the handle
> > as integer. You will have to find some way to associate handle as
> > integer with handle as HWND__.  Once you find it, you can use
> > "make_constructor" functionality, which is also supported by py++.
> >
> > HTH.
> > _______________________________________________
> > Cplusplus-sig mailing list
> > [hidden email]
> > http://mail.python.org/mailman/listinfo/cplusplus-sig
> >
>


--
Technology & Consulting Services - ned Productions Limited.
http://www.nedproductions.biz/. VAT reg: IE 9708311Q.
Work Portfolio: http://careers.stackoverflow.com/nialldouglas/



_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig


_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Wrapping and Passing HWND with Boost.Python

Ehsan Pi
In reply to this post by Roman Yakovenko
Thanks Roman,

I believe these are not specific to py++ but boost.python, correct? What I mean is whether it can be automated through the py++ wrapper, or do I have to manually alter the py++ generated cpp file? 

Regards,
Ehsan

On Mon, Apr 30, 2012 at 3:00 PM, Roman Yakovenko <[hidden email]> wrote:
On Mon, Apr 30, 2012 at 9:54 PM, Ehsan Pi <[hidden email]> wrote:
> Thanks Roman for your quick reply,
>
> That's what confuses me. HWND is essentially a pointer to an int to hold the
> window handle. How can to convert them to each other?

I am not sure that you are right, but in case you are, use
make_constructor and reinterpret_cast.

Regards,
Roman
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig


_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Wrapping and Passing HWND with Boost.Python

Roman Yakovenko
On Tue, May 1, 2012 at 5:25 PM, Ehsan Pi <[hidden email]> wrote:
> Thanks Roman,
>
> I believe these are not specific to py++ but boost.python, correct?

Yes

> What I
> mean is whether it can be automated through the py++ wrapper, or do I have
> to manually alter the py++ generated cpp file?

Yes. py++ supports opaque pointers and code injection. The
documentation contains explanation for different use cases.
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Wrapping and Passing HWND with Boost.Python

Ehsan Pi
Thanks again. I'll give it a try as soon as I get a chance.

On Tue, May 1, 2012 at 10:37 AM, Roman Yakovenko <[hidden email]> wrote:
On Tue, May 1, 2012 at 5:25 PM, Ehsan Pi <[hidden email]> wrote:
> Thanks Roman,
>
> I believe these are not specific to py++ but boost.python, correct?

Yes

> What I
> mean is whether it can be automated through the py++ wrapper, or do I have
> to manually alter the py++ generated cpp file?

Yes. py++ supports opaque pointers and code injection. The
documentation contains explanation for different use cases.
_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig


_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Wrapping and Passing HWND with Boost.Python

Niall Douglas
In reply to this post by Ehsan Pi
Cython is the easiest. But using the C API for this is extremely
easy. Just pull the integer and cast to size_t and then void *.

Niall

On 1 May 2012 at 10:21, Ehsan Pi wrote:

> Thanks Niall for your response and correction on HWND.
> I'm new to Python (and Boost.Python for that matter) and thought Python was
> not typed. If not, how can one convert Python integers to void*? Googled
> but didn't find an answer.
>
> Regards,
> Ehsan
>
>
> On Tue, May 1, 2012 at 9:18 AM, Niall Douglas <[hidden email]>wrote:
>
> > A HWND is always a void * i.e. an opaque pointer. Unfortunately some
> > people using BPL think that BPL can't handle opaque pointers, so they
> > do fun stuff like use a thunk struct type for void * instead, and
> > wrap the lot in manual pointer casting. It's far easier just to
> > declare it an opaque pointer and be done with it.
> >
> > It is very unfortunate indeed that win32gui returns a HWND as an
> > integer. It isn't an integer and must not be treated as one. Still,
> > it's easy to write a routine which converts python integers to void
> > *.
> >
> > Niall
> >
> >
> > On 30 Apr 2012 at 14:54, Ehsan Pi wrote:
> >
> > > Thanks Roman for your quick reply,
> > >
> > > That's what confuses me. HWND is essentially a pointer to an int to hold
> > > the window handle. How can to convert them to each other?
> > >
> > > Ehsan
> > >
> > > On Mon, Apr 30, 2012 at 2:46 PM, Roman Yakovenko
> > > <[hidden email]>wrote:
> > >
> > > > On Mon, Apr 30, 2012 at 9:11 PM, Ehsan Pi <[hidden email]> wrote:
> > > > > In python I get the not-match error:
> > > > >
> > > > >     >>> import MyWrapper
> > > > >     >>> import win32gui
> > > > >     >>> hwnd = win32gui.GetDesktopWindow()
> > > > >     >>> foo = MyWrapper.Foo(hwnd)
> > > > >     Traceback (most recent call last):
> > > > >       File "<stdin>", line 1, in <module>
> > > > >     Boost.Python.ArgumentError: Python argument types in
> > > > >         Foo.__init__(Foo, int)
> > > > >     did not match C++ signature:
> > > > >         __init__(struct _object *, struct HWND__ * window)
> > > > >     >>>
> > > > >
> > > > > How can I correct this problem to be able to pass a window's handle
> > (from
> > > > > win32gui) in Python to C++ class, and interact with it?
> > > >
> > > > I think the error is pretty clear: the exported constructor expects a
> > > > pointer to some struct(?) HWND__, while, win32gui returns the handle
> > > > as integer. You will have to find some way to associate handle as
> > > > integer with handle as HWND__.  Once you find it, you can use
> > > > "make_constructor" functionality, which is also supported by py++.
> > > >
> > > > HTH.
> > > > _______________________________________________
> > > > Cplusplus-sig mailing list
> > > > [hidden email]
> > > > http://mail.python.org/mailman/listinfo/cplusplus-sig
> > > >
> > >
> >
> >
> > --
> > Technology & Consulting Services - ned Productions Limited.
> > http://www.nedproductions.biz/. VAT reg: IE 9708311Q.
> > Work Portfolio: http://careers.stackoverflow.com/nialldouglas/
> >
> >
> >
> > _______________________________________________
> > Cplusplus-sig mailing list
> > [hidden email]
> > http://mail.python.org/mailman/listinfo/cplusplus-sig
> >
>


--
Technology & Consulting Services - ned Productions Limited.
http://www.nedproductions.biz/. VAT reg: IE 9708311Q.
Work Portfolio: http://careers.stackoverflow.com/nialldouglas/



_______________________________________________
Cplusplus-sig mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/cplusplus-sig
Loading...