gpt4 book ai didi

python - Windows 常用项对话框 : ctypes + COM access violation

转载 作者:太空狗 更新时间:2023-10-29 21:47:06 28 4
gpt4 key购买 nike

我正在尝试使用 ctypes 模块来调用 Windows 的 Common Item Dialog API .下面显示的代码大致基于 MSDN documentation 中概述的步骤。 .它唯一的依赖是 comtypes.GUID 模块。

import ctypes
from ctypes import byref, POINTER, c_int, c_long
from ctypes.wintypes import HWND, HRESULT
from comtypes import GUID

CLSID_FileOpenDialog = '{DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7}'
IID_IFileDialog = '{42F85136-DB7E-439C-85F1-E4075D135FC8}'
#IID_IFileOpenDialog = '{D57C7288-D4AD-4768-BE02-9D969532D960}'
CLSCTX_SERVER = 5
COINIT_APARTMENTTHREADED = 2
FOS_PICKFOLDERS = 32
FOS_FORCEFILESYSTEM = 64

ole32 = ctypes.windll.ole32
CoCreateInstance = ole32.CoCreateInstance
CoInitializeEx = ole32.CoInitializeEx

CoInitializeEx(None, COINIT_APARTMENTTHREADED)

ptr = c_int()
error = CoCreateInstance(
byref(GUID(CLSID_FileOpenDialog)), None, CLSCTX_SERVER,
byref(GUID(IID_IFileDialog)), byref(ptr))
assert error == 0

ptr = ptr.value
c_long_p = ctypes.POINTER(ctypes.c_int)
print('Pointer to COM object: %s' % ptr)
vtable = ctypes.cast(ptr, c_long_p).contents.value
print('Pointer to vtable: %s' % vtable)

func_proto = ctypes.WINFUNCTYPE(HRESULT, HWND)

# Calculating function pointer offset: 3rd entry in vtable; 32-bit => 4 bytes
show_p = ctypes.cast(vtable + 3*4, c_long_p).contents.value
print('Pointer to show(): %s' % show_p)
show = func_proto(show_p)
show(0)

在第一次调用 show(0) 之前,一切都按预期工作:

 WindowsError: exception: access violation reading 0xXXXXXXXX

(输出可能不同。)为了比较,我在 AutoHotkey_L 中执行了相同的步骤,它可以直接访问 COM。

CLSID := "{DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7}"
IID := "{42F85136-DB7E-439C-85F1-E4075D135FC8}"

ptr := ComObjCreate(CLSID, IID)
vtable := NumGet(ptr + 0, 0, "Ptr")
show := NumGet(vtbl + 0, 3 * A_PtrSize, "Ptr")

MsgBox ptr: %ptr% vtable: %vtable% show: %A_PtrSize%

DllCall(show, "Ptr", ptr, "Ptr", 44)

生成的宏会按预期弹出“打开文件”对话框。两种情况下 vtable 指针偏移量相同,但只有 Python 版本会引发访问冲突。

任何人都可以阐明这一点吗?

[我很抱歉没有在适当的地方添加更多的超链接,但作为一个新用户,我一次只能添加两个。]

背景:我正在组装一个轻量级模块,它提供了一个本地保存/打开文件对话框以供在 Python 脚本中使用。到目前为止,我一直无法找到纯 Python 的实现。那些现有的依赖于 UI 工具包,例如 Tkinter 或 wxPython。

最佳答案

解决方法如下:

COM 方法采用附加参数:“this”指针。当您从 C++ 调用方法时,它是隐式的,在 C(和 ctypes)中,您必须自己提供它。

换行

func_proto = ctypes.WINFUNCTYPE(HRESULT, HWND)

进入

func_proto = ctypes.WINFUNCTYPE(HRESULT, c_long, HWND)

还有这一行

show(0)

进入

show(ptr, 0)

您的代码将起作用。

关于python - Windows 常用项对话框 : ctypes + COM access violation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12632519/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com