如何在 idl 中声明 IStream,以便 Visual Studio 将其映射到 s.w.interop.comtypes?

2023-12-04

我有一个 COM 对象,需要从 C# 客户端获取流并对其进行处理。看来我应该使用 IStream。所以我像下面这样写我的idl。然后我使用 MIDL 编译为 tlb,编译我的解决方案,注册它,然后将对我的库的引用添加到 C# 项目。

Visual Studio 在我自己的库中创建 IStream 定义。我怎样才能阻止它这样做,并让它使用 COMTypes IStream?似乎会有 3 个答案之一: 添加一些导入

  • 到 idl,这样它就不会重新声明 IStream(导入 MSCOREE 可以做到这一点,但不能解决 C# 问题)
  • 以某种方式在 Visual Studio 中为 IStream 别名 - 但我不知道如何做到这一点。
  • 我所有的想法都是完全错误的,我根本不应该使用 IStream

帮助...谢谢

[
  uuid(3AC11584-7F6A-493A-9C90-588560DF8769),
  version(1.0),
]
library TestLibrary
{

  importlib("stdole2.tlb");

  [
    uuid(09FF25EC-6A21-423B-A5FD-BCB691F93C0C),
    version(1.0),
    helpstring("Just for testing"),
    dual,
    nonextensible,
    oleautomation
  ]
  interface ITest: IDispatch
  {
    [id(0x00000006),helpstring("Testing stream")]
    HRESULT _stdcall LoadFromStream([in] IStream * stream, [out, retval] IMyTest ** ResultValue);
  };

  [
    uuid(CC2864E4-55BA-4057-8687-29153BE3E046),
    noncreatable,
    version(1.0)
  ]
  coclass HCTest
  {
     [default] interface ITest;
  };

};

您所看到和体验的是 MIDL 编译器的一项功能(通常是令人讨厌的功能)。 “库”部分中引用的任何类型都将其定义注入到 tlb(类型库)中;除了 IUnknown 接口和MIDL 基本类型,(也许还有一些更原始的类型)。您在“您的”IStream 上看到的那些奇怪的方法来自基本类型 ISequentialStream。您有几个选择:

  1. 与 MIDL 编译器进行了数天的斗争,试图让它免于注入 IStream(及其所有其他支持类型)。我已经做到了这一点。也是和 Mcoree 一起。问题在于,MIDL 编译器在遇到库语句时会自动导入“oaidl.idl”。因此,在您有机会对其执行任何操作之前,这些类型(Stream 等)已经被注入到当前的 IDL 上下文中。这是一个记录很少的功能。最重要的是,无论您做什么,它都会执行此操作,除非您删除对 IStream 的硬引用(使用 PVOID [*] 流)。

  2. 忽略它。甚至不要使用它。请改用 System.Runtime.InteropServices.ComTypes.IStream。只要您使用的接口(在 .Net 中)标有正确的属性(Guid、InterfaceType 等),它们就可以互换。您必须编辑类型库或互操作代码,以便它接受您希望传递的类型。我会选择对象,这样您就可以使用任何 IStream 接口(具有有效的定义)。并且不要使用旧的 TlbImp 工具。使用新的 TlbImp2(用 C# 编写且开源)https://clrinterop.codeplex.com/releases/view/17579。它允许您真正自定义从 TLB 到托管的转换,并且您可以让它生成源文件,而不是/除了编译的互操作 dll 之外。

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

如何在 idl 中声明 IStream,以便 Visual Studio 将其映射到 s.w.interop.comtypes? 的相关文章