如何从非托管 COM dll 生成类型库

Posted

技术标签:

【中文标题】如何从非托管 COM dll 生成类型库【英文标题】:How to generate type library from unmanaged COM dll 【发布时间】:2011-06-26 18:40:37 【问题描述】:

我必须在我的 .NET 应用程序中使用第三方非托管 COM dll。我需要修改此程序集以生成custom RCW。为了Edit Interop Assembly,我需要特定程序集的类型库。谁能解释一下?

regsvr32中没有生成类型库的选项。

谢谢, 最好的祝福, 机器人。

【问题讨论】:

【参考方案1】:

您需要OLE-COM Object Viewer,它是最新Windows SDK 的一部分。然后您可以转到 File->View Type Lib 并将 IDL 保存到文本文件中。然后,您可以使用MIDL(也是 Windows SDK 的一部分)重新生成 TLB 和头文件。对于基本情况,应该这样做:

midl /out c:\temp /header MyHeader.h MyIDLFile.idl

【讨论】:

嗨,Guido 非常感谢。但我收到以下错误。我会用谷歌搜索它并将其缩短。 [.\Sample.IDL(60):error MIDL2025:syntax error : Expecting a type specification near "single"]【参考方案2】:

如果您只想从本机 dll 创建一个互操作程序集(并且本机 DLL 将 TLB 作为资源嵌入),您可以直接在 dll 上调用 tlbimp:

tlbimp Foo.dll /out:Interop.Foo.dll

这将生成 Interop.Foo.dll。然后可以使用 ildasm 来修改 IL:

ildasm Interop.Foo.dll /out=Foo.il

【讨论】:

实际上我认为 tlbimp 需要 Foo.tlb 来生成 Interop.Foo.dll,正如 linkEdit Interop Assembly 中所解释的那样。感谢您的提示【参考方案3】:

如果你只有那个 COM DLL,你就不能生成类型库。类型库描述了实现的 COM 接口。但非托管 COM DLL 只需要公开DllGetClassObject。这只会给你一个IClassFactory,如果你事先知道正确的类型,它可以让你创建新对象。

【讨论】:

类型库可以在DLL资源中,然后可以被OleView查看并重构。 @sharptooth:确实在某些情况下您已经嵌入了类型库。但是这个问题没有任何意义。 Tlbimp.exe可以解析DLL中的typelibs(使用inputDLL\1指定资源号)【参考方案4】:

如果 typelib 嵌入在 DLL 资源中并且 TLB 文件本身是必需的,那么第 3 方软件可以提取它(尽管正如其他人指出的那样,这可能不是最理想的选择)。

例如使用Resource Hacker:

    打开 DLL 文件。 导航到树视图中的 TYPELIB\1\1033(或其他)节点。 从菜单中选择操作 -> 将资源另存为二进制文件... 选择一个文件名并为其指定 .TLB 扩展名。

您现在可以引用该 .TLB 文件并在不需要原始 DLL 的情况下进行构建,例如

#import "test.tlb" named_guids

【讨论】:

【参考方案5】:

Visual Studio IDE 可以直接从非托管的 .exe 和 .dll 文件中提取二进制资源。 如果类型库作为二进制资源保存在 非托管 COM DLL(例如使用 VS 原生 C++ 编译器构建的)中,您可以按如下方式提取它:

    在 VS 资源编辑器(打开可执行文件时的默认编辑器)中打开 .dll 文件。 导航到资源树中的类型库资源("TYPELIB",然后是1)。 右键单击类型库资源并选择export。这会弹出一个“将文件另存为”对话框。 在“文件另存为”框中,将文件名从默认(通常为bin1.bin)更改为MyLibrary.tlb 之类的名称,然后点击确定。 使用OleView.exe 打开导出的.tlb 文件进行确认(结果应该与使用OleView.exe 打开.dll 看到的结果相同)。

要从 托管 DLL(例如,使用 C# 构建的那些)中提取类型库,VS 包含工具 Tlbexp.exe(从 VS 命令提示符运行它): https://msdn.microsoft.com/en-us/library/hfzzah2c(v=vs.110).aspx

【讨论】:

以上是关于如何从非托管 COM dll 生成类型库的主要内容,如果未能解决你的问题,请参考以下文章

从非托管 dll 文件(注入到正在运行的进程中)调用托管 dll

从非托管进程中卸载 .NET DLL

gcServer 设置未从非托管 exe 传递到托管 dll

从非托管 DLL 导入函数时,0x8007007F 是啥意思?

从非托管 C++ mfc active x dll 启动 C# 对话框

从非托管 C++ 配置 .NET 库