Skip to main content
 首页 » 编程设计

python之使用 Boost.Python 包装和传递 HWND

2025年05月04日10lonelyxmas

我为 C++ 遗留类创建了一个 Boost.Python 包装器(使用 Py++),该类在其构造函数中采用 HWND 窗口句柄。但是,当我尝试使用它时将模块导出到 python 后,出现类型不匹配错误。

这是我包装的 C++ 类:

// File Foo.hpp 
// 
#include "Windows.h" 
class Foo 
{ 
public: 
    Foo( const HWND window ){} 
 
    virtual ~Foo(){} 
 
    virtual int Bar( int num ) { return num; } 
};    

Py++ 输出:

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 ) 

生成的包装器:

#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") ) ); 
 
        } 
    } 
} 

在 python 中我得到不匹配错误:

>>> 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) 
>>> 

如何更正此问题,以便能够将 Python 中的窗口句柄(来自 win32gui)传递给 C++ 类,并与之交互?

环境: Visual Studio 2008、Boost 1.44、gcc-xml 0.9.0、py++ 1.0.0、pygccxml 1.1.0

请您参考如下方法:

您不能假设 boost python 生成的包装类型与其他工具使用的包装过程兼容。在这种情况下,win32 gui 是使用 SWIG 构建的,它可以引入额外的 C、C++ 和 python 代码层(取决于要包装的类型)以生成正确的代码。

您可以在 pywin32 mercurial repository 中看到 GetDesktopWindow(以及许多其他函数)的 SWIG 接口(interface)文件