1

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

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

  • 到 idl 所以它不会重新声明 IStream(导入 MSCOREE 会这样做,但不能解决 C# 问题)
  • 以某种方式在视觉工作室中为 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;
  };

};
4

2 回答 2

1

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

  1. 与 MIDL 编译器搏斗了几天,试图通过注入 IStream(及其所有其他支持类型)来获取它。我已经做到了。Mscoree 也是如此。问题是 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。

于 2014-09-24T08:46:15.253 回答
0

这不需要修复,从类型库创建的互操作包装器就可以了。ComTypes.IStream 声明允许托管代码实现 COM 服务器,该服务器实现 IStream 或将 IStream 作为参数。许多 .NET 框架类都可以。

于 2010-04-22T14:59:21.947 回答