使用 COM 对象的 Python ctypes 和 DLL

2024-04-12

在 Windows 下,我尝试使用第 3 方 DLL (SomeLib.dll)使用 Python 2.7 用 C++ 编程ctypes。 对于其某些功能,该库使用另一个 COM DLL (SomeCOMlib.dll),它本身使用其他DLL(LibA.dll).

请注意,这并不是直接从 Python 使用 COM DLL,而是使用从 Python 中使用 COM DLL 的 DLL。

为了使与 Python 的集成更容易,我将我想要使用的调用分组到一个新的 DLL 中我自己的函数中(MyLib.dll),也是用 C++ 编程,只是为了进行调用ctypes更方便(使用extern "C"并针对特定场景定制功能)。 本质上,我的库公开了 2 个函数:doSomethingSimple(), doSomethingWithCOMobj()(全部返回void,无参数)。

“有效”依赖层次结构如下:

MyLib.dll
  SomeLib.dll
    SomeCOMlib.dll
      LibA.dll

我能够编写一个简单的 C++ 控制台应用程序 (Visual C++),它使用MyLib.dll并连续两次拨打电话都没有问题。

使用 Python/ctypes,第一个调用工作正常,但是使用 COM 的调用会抛出WindowsError: [Error -529697949] Windows Error 0xE06D7363。 从库的其余行为中,我可以看到问题正是发生在进行 COM 调用的地方。

(简单的测试 C++ 应用程序也会或多或少地在同一个地方失败,如果LibA.dll丢失了,但我不确定它是否相关。)

我使用以下命令查看了依赖关系层次结构依赖步行者 http://www.dependencywalker.com/. SomeCOMlib.dll没有被列为依赖项SomeLib.dll,尽管这是明确要求的,并且LibA.dll没有被列为依赖项SomeCOMlib.dll,尽管在运行时也明确需要它。

我从命令行、这些 DLL 所在的目录中运行所有内容(并且 C++ 示例可执行文件工作正常)。 我尝试强制 PATH 包含该目录,并且还尝试将 DLL 复制到我猜测可能会被拾取的各个位置(C:\Windows\System32 and C:\Python27\DLLs), 没有成功。SomeCOMlib.dll还注册了regasm.exe.

是什么导致在普通 C++ 应用程序和 Python 应用程序中使用此 DLL 之间存在这种差异?ctypes当涉及到它自己对 COM 机制的使用(以及可能随后加载其他 DLL)时?

哪些步骤至少可以提供比以下更多的信息Windows Error 0xE06D7363从Python,能够进一步调查问题?

Python 代码如下所示:

import ctypes
myDll = ctypes.WinDLL("MyLib.dll")
myDll.doSomethingSimple()
myDll.doSomethingWithCOMobj() # This statement throws the Windows Error

(测试 C++ 独立应用程序有效,链接到MyLib.dll内进行完全相同的调用main.)


当您需要进程内 COM 对象时,您不必直接链接到实现的 DLL。你通常使用CoCreateInstance http://msdn.microsoft.com/en-us/library/windows/desktop/ms686615(v=vs.85).aspx/CoCreateInstanceEx http://msdn.microsoft.com/en-us/library/windows/desktop/ms680701(v=vs.85).aspx,它将为您加载 DLL。

查找过程会经过应用程序的清单 http://msdn.microsoft.com/en-us/library/windows/desktop/aa374191(v=vs.85).aspx及其依赖的装配清单 http://msdn.microsoft.com/en-us/library/windows/desktop/aa374219(v=vs.85).aspx。这样做是为了支持免注册COM http://msdn.microsoft.com/en-us/library/windows/desktop/aa375134(v=vs.85).aspx.

If there's no application manifest or if none of the dependant assembly manifests declare your class in a comClass XML element, the lookup defaults to the registry, which will check HKEY_CLASSES_ROOT\CLSID http://msdn.microsoft.com/en-us/library/windows/desktop/ms691424(v=vs.85).aspx1 for a subkey named {<your-CLSID>}, itself with an InProcServer32 http://msdn.microsoft.com/en-us/library/windows/desktop/ms682390(v=vs.85).aspx subkey stating the DLL.

这解释了为什么 SomeCOMlib.dll 不显示为依赖项。它没有解释为什么 LibA.dll 没有作为它的依赖项出现,可能是因为它是动态加载的。如果您在 Dependency Walker 中分析您的应用程序,您将在底部窗格中看到 LoadLibrary 调用的日志。要对其进行分析,请在 Dependency Walker 中打开 Python 可执行文件,然后转到菜单选项 Profile->Start profiling...,设置参数以运行您的.py文件并单击“确定”。

0xE06D7363异常代码是Visual C++ 异常代码 http://support.microsoft.com/kb/185294。你应该检查一下源代码doSomethingWithCOMobj。要调试它,请使用您喜欢的工具(Visual C++、WinDbg 等),打开 Python 的可执行文件,设置参数以运行您的程序.py文件,并在运行应用程序之前在函数的第一个语句上启用断点。然后运行它并逐步执行每条指令。

确实很难猜测您的本机 C++ 应用程序和 Python 有什么不同,但 Python 和 Python 使用的 COM 初始化参数可能不同。doSomethingWithCOMobj,或者你还没有声明它__stdcall(尽管是一个无效函数,这并不重要),或者它尝试写入标准输出并且您正在使用pythonw.exe这不是控制台应用程序等。


1. HKEY_CLASSES_ROOT is a mix of HKEY_CURRENT_USER\Software\Classes and HKEY_LOCAL_MACHINE\Software\Classes.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 COM 对象的 Python ctypes 和 DLL 的相关文章

随机推荐

  • 将服务器端渲染添加到 create-react-app

    我正在研究 create react app 和 SSR 我在这个 repo 中添加了 redux 和 react router gt https github com sarovin StarteKit https github com
  • 无法使用 hist() 函数对齐日期时间对象直方图中的分箱

    所以我试图绘制一些日期时间对象的直方图 但我永远无法让垃圾箱与条形图对齐 我的代码如下 我首先导入我的内容并声明开始 结束和一天对象 import datetime import matplotlib pyplot as plt end d
  • 按距离对邮政编码邻近搜索进行排序(php/mysql)

    我有一个表 用户邮政编码 其中包含用户的邮政编码 纬度和经度 我在 stackoverflow 上找到了一个函数 可以查找特定半径内的邮政编码 function zipcodeRadius lat lon radius global mys
  • (_hidden#919_:0) 崩溃符号文件内

    我正在尝试手动符号化崩溃日志 因为 Xcode 7 不会为我做这件事 然而 我得出了这个结果 这是什么意思 我能用它做什么 我也使用过atos 它只是给了我相同的地址 我确信我有正确的 dSYM app 和日志 Thanks When yo
  • 是什么破坏了 .net 二进制 (dll) 接口

    考虑两个 net dll 首先 application dll 包含主要业务逻辑和数据访问代码 第二个 webservice dll 主要由 WebMethod 组成 这些 WebMethod 链接到 application dll 的对象
  • 如何在 rmarkdown 中格式化 sessionInfo() ?

    如果我想在 R 中很好地打印 PDF 中的 sessionInfo 我可以使用 toLatex sessionInfo 似乎应该有一个类似的选项让 rmarkdown 在 HTML 中呈现 但我在这里或 Rdocumentation 上找不
  • 如何在android中制作水平滚动视图

    我想做这种水平滚动 看图片 gt gt gt gt XML 文件保存在 res layout main xml 我的 main xml 文件有错误吗 我想用
  • 如何在没有 root 权限的情况下创建多分区 SD 磁盘映像?

    是否可以在没有 root 权限 即无环回挂载 的情况下在 linux 中创建完整的 SD 映像 我正在寻找一种自动化嵌入式系统映像创建的方法 该映像应包含特定的分区结构以及格式化为 FAT 和 ext2 的分区 并填充来自构建系统的文件 最
  • 表达式“b=(b-x)&x”是什么意思?

    假设 x 是一个集合 以下代码将遍历集合 x 的子集 int b 0 do process subset b while b b x x 我读到了有关位操作及其如何用于表示集合的读物 表达什么意思b b x x意思是 它是如何工作的 我熟悉
  • WPF TreeView ObservableCollection 通知示例代码

    我正在尝试编写一个 C WPF 应用程序 但我被 TreeView 和 ObservableCollection 困住了 这是我的 TreeView 项目 Root SubItem SubItem Root SubItem SubItem
  • React:动态导入jsx

    这个问题与将 JSX 文件动态导入 React 相关 基本上 我们有一个主要组件 它根据数据库中存储的结构动态呈现其他组件 动态组件存储在子目录 Components 中 我们静态地将 this 定义为 import CompA from
  • 通过处理 NC_HITTEST 移动控件时设置 SizeAll 光标

    我写了WndProc可移动控件的方法如下 protected override void WndProc ref Message m const int WM NCHITTEST 0x0084 if m Msg WM NCHITTEST b
  • ios::noreplace 的 C++ 替换

    我正在使用 fstream 打开文件进行写入 我不想覆盖现有文件 因此经过一番搜索后 我发现了 ios noreplace 但是当我编译这个时 include
  • sklearn“管道实例尚未安装。”错误,尽管它是

    已经提出了类似的问题 但答案并没有帮助我解决我的问题 即使整个管道都安装了 管道中的 Sklearn 组件也没有安装 https stackoverflow com questions 58704347 sklearn components
  • 雄辩的 MYSQL 语句:WHERE NOT(A OR B)

    我正在开发日期范围重叠功能 可以用 13 个正条件编写该功能来检查日期间隔是否重叠 https en wikipedia org wiki Allen 27s interval algebra https en wikipedia org
  • 播放音频并单击重新启动

    我正在寻找在 HTML5 音频播放器中重新启动音频文件 我定义了一个音频文件和一个play button
  • Python 中的自动 ARIMA 导致趋势拟合预测不佳

    ARIMA 新手 尝试使用自动 ARIMA 在 Python 中对数据集进行建模 我正在使用 auto ARIMA 因为我相信它会更好地定义 p d 和 q 的值 但结果很差 我需要一些指导 请参阅下面我的可重复尝试 尝试如下 DEPEND
  • 如何在标题和桑基图之间添加更多空间?

    我使用 python 和plotly 来创建桑基图 这是标题 副标题的文本和问题的图片 标题与图表重叠 如何在两者之间创造更多空间 我尝试在布局中添加 height 但这会改变我的桑基图的宽度 line2 From time str tim
  • PHPMyAdmin 中没有结果

    使用 Mysql 控制台 set Name CONCAT seq 0 to DATEDIFF 2015 12 15 2015 12 05 1 Query OK 0 rows affected 0 00 sec MariaDB test gt
  • 使用 COM 对象的 Python ctypes 和 DLL

    在 Windows 下 我尝试使用第 3 方 DLL SomeLib dll 使用 Python 2 7 用 C 编程ctypes 对于其某些功能 该库使用另一个 COM DLL SomeCOMlib dll 它本身使用其他DLL LibA