我认为其他任何答案实际上都没有回答“做stdole.dll
什么”的大部分问题。这是我的理解。
概括:
此 DLL 位于从托管应用程序最终指向非托管操作系统 DLL 的引用链的顶部附近,如下所示:
.NET app -->
stdole.dll -->
stdole2.tlb -->
oleaut32.dll
这条链中的链接定义明确但晦涩难懂。这个答案的其余部分走链......
详细解释:
stdole.dll
它本身就是一个互操作 DLL。这意味着它是一个 .NET 程序集,其目的基本上是充当具有 COM 接口的特定非托管类的包装器。如果您使用ILSpy或 dotPeek 之stdole.dll
类的工具查看内部,您可以看到里面有什么。下面是一个接口示例:StdPicture
using System.Runtime.InteropServices;
namespace stdole
{
[CoClass(typeof (StdPictureClass))]
[Guid("7BF80981-BF32-101A-8BBB-00AA00300CAB")]
[ComImport]
public interface StdPicture : Picture
{
}
}
所有这些都是一个带有属性的接口,这些属性对真正应该使用的 COM 类的详细信息进行编码。像这样的 DLL 通常是使用类似工具自动创建的,tlbimp.exe
或者当您将非托管 COM DLL 作为参考直接添加到项目中时,Visual Studio 会为您执行此操作。
我们可以再深入一点。Guid
上面示例中的A7BF80981-BF32-101A-8BBB-00AA00300CAB
通常会在 Windows 注册表中找到,这是运行时stole.StdPicture
在实际从托管代码中使用时要查看的位置。
如果您使用 RegEdit 搜索该 GUID,您会发现:
Computer\HKEY_CLASSES_ROOT\Interface\{7BF80981-BF32-101A-8BBB-00AA00300CAB}\TypeLib
具有价值 00020430-0000-0000-C000-000000000046
。
搜索该值,您会发现:
Computer\HKEY_CLASSES_ROOT\TypeLib\{00020430-0000-0000-C000-000000000046}
(来自同一 DLL 的大多数其他 GUID 可能会有类似的条目)。
这个键有很多有趣的细节,实际上是底层实现的几个版本的细节。例如,在 subkey 下 2.0\0\win32
,默认值为:
C:\WINDOWS\SysWow64\stdole2.tlb
对于版本 2 的 32 位变体。这更接近StdPicture
实际实现的位置。
TLB 文件只是 DLL 的 COM“头”。它本身没有可执行代码。在OLEViewDotNet或原始OleViewstdole2.tlb
之类的工具中打开,您可以读取类型库本身的 IDL。在这种情况下,第一部分具有以下内容:
// typelib filename: stdole2.tlb
[
uuid(00020430-0000-0000-C000-000000000046),
version(2.0),
helpstring("OLE Automation")
]
library stdole
{
...
}
请注意,uuid
我们从上面的 Regedit 获得的值相同。最终向下滚动,我们来到StdPicture
条目,与上面的示例相同:
[
uuid(0BE35204-8F91-11CE-9DE3-00AA004BB851)
]
coclass StdPicture {
...
};
再一次,这里没有真正的代码,只是一个类定义。回到 RegEdit 我们可以发现uuid
:
Computer\HKEY_CLASSES_ROOT\CLSID\{0BE35204-8F91-11CE-9DE3-00AA004BB851}\InprocServer32
其值为C:\Windows\System32\oleaut32.dll
。现在我们知道这个 DLL 实现StdPicture
了 32 位stdole
库版本 2 的 coclass。
(虽然我会认为这个文件应该在SysWow64
......?)
如果您要按照此链获取其他接口,您可能最终会使用相同的 DLL 或另一个。
请注意,对于某些语言(如 VB6),TLB 通常直接嵌入到实现的 DLL 中。但这不是 COM 所必需的,显然微软在这种情况下是如何做到的。