如何在idl中声明一个IStream,以便visual studio将其映射到swinterop.comtypes?

我有一个COM对象需要从C#客户端获取流并处理它。 看来我应该使用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; }; }; 

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

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

  1. 与MIDL编译器搏斗了好几天,试图通过注入IStream(及其所有其他支持类型)来获取它。 我做到了这一点。 它也是Mscoree。 问题是MIDL编译器在遇到库语句时会自动导入“oaidl.idl”。 所以那些类型(Stream等)已经注入到当前的IDL上下文中,然后才有可能对它做任何事情。 这是一个记录不完整的function。 除非你删除对IStream的硬引用(使用PVOID [*]流),否则无论你做什么,底线都是这样做的。

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