python - 如何使用 SWIG 包装 HWND 和 HINSTANCE 类型?
问题描述
我正在用 SWIG 包装第三方提供的 Windows DLL,以便在 Python 中使用。我已经能够成功编译我的 SWIG 模块并将其导入 Python,但是我遇到了一个函数(来自.h
头文件)的问题:
_APPFN ServerID _CALLCONV OpenServer(HINSTANCE hAppInst, HWND hWnd);
我在使用这个函数时遇到了问题,因为我没有PythonHINSTANCE
或HWND
Python 的类型。根据此函数的文档,这些值可以是 null、0 或基本上任何值(目前是一个未使用的功能),所以我试图弄清楚如何使用typemap
这些整数来生成这些整数,这样我就可以传入 0。从我的.i
文件:
/* handle HINSTANCE */
%typemap(in) HINSTANCE {
$1 = PyInt_AsLong($input);
}
/* handle hwnds */
%typemap(in) HWND {
$1 = PyInt_AsLong($input);
}
当我尝试使用上述类型映射编译我的包装文件(我正在使用 Visual Studio)时,我收到错误:cannot convert from 'long' to 'HINSTANCE'
和cannot convert from 'long' to 'HWND'
.
根据我的阅读,我相信HINSTANCE
andHWND
是“结构”,因此我需要做一些事情才能将结构“转换”为整数,但不幸的是,这一切都超出了我的想象。我主要是一个自学成才的 Python 程序员,处理 C/C++ 数据类型相当混乱。
我希望有人可以看看我在做什么,并指导我如何更改我的类型映射。
解决方案
这些类型是void*
每个 Microsoft 文档:
https ://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
虽然可以肯定的是,cppyy(通过 Clang 解析 Windows 标头)将它们解析为指向不透明类型的指针(即前向声明,但未定义):
$ python
>>> import cppyy
>>> print(cppyy.gbl.HWND)
<cppyy.TypedefPointerToClass object at 0x00000245E8839558>
>>>
因此,如果您想确定的话,您可能需要查找 typedef。
但是,无论 HWND 和 HINSTANCE 是指向不透明类的指针还是指向 的指针void
,即使您可以在 32b Windows 上强制转换它们,但在 64b 中从long
to void*
(或“ opaque*
”)强制转换将不起作用,因为该long
值将被截断。所以,在你的类型图中使用PyLong_AsVoidPtr
而不是PyInt_AsLong
。请参阅 Python C-API 文档:
https ://docs.python.org/3/c-api/long.html#c.PyLong_AsVoidPtr
如果类型是不透明的类,您还需要显式转换,最终代码如下所示:
/* handle HINSTANCE */
%typemap(in) HINSTANCE {
$1 = (HINSTANCE)PyLong_AsVoidPtr($input);
}
/* handle hwnds */
%typemap(in) HWND {
$1 = (HWND)PyLong_AsVoidPtr($input);
}
当然,如果两者HWND
和HINSTANCE
确实都void*
符合 Microsoft 文档页面,那么该演员阵容将是无效的。
推荐阅读
- angular - Angular / Type脚本如何从json对象打印值
- google-pagespeed - html缩小不再是一个因素?
- html - 在 Expo 中将 HTML 格式的文本设置为剪贴板
- java - 在 Java Android Studio 中删除对话框周围的触摸
- java - 从 Spring AMQP Rabbit Consumer 捕获异常
- amazon-web-services - 如何使用 Access-Control-Allow-Origin 提供 AWS S3 文件:* 标头
- c++ - 试图让它在读数之间等待 1 秒(C++ Arduino)
- php - 无法在 mac 上安装 PHP 8
- html - 移动菜单未正确对齐
- java - 静态java方法