我有一个COM对象需要从C#客户端获取流并对其进行处理。看来我应该使用IStream。所以我写下我的idl。然后我使用MIDL编译为tlb,编译我的解决方案,注册它,然后将我的库的引用添加到C#项目。
Visual Studio在我自己的库中创建一个IStream定义。如何阻止它这样做,让它使用COMTypes IStream?似乎有3个答案之一: 添加一些导入
帮助...谢谢
[
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;
};
};
答案 0 :(得分:1)
您所看到和体验的是MIDL编译器的一个功能(通常很烦人)。在"库中引用的任何类型" section将其定义注入tlb(类型库);除了IUnknown接口和MIDL base types之外,(可能还有一些更原始的类型)。你看到的那些奇怪的方法"你的" IStream来自基类型ISequentialStream。您有几个选择:
与MIDL编译器搏斗了好几天,试图通过注入IStream(及其所有其他支持类型)来获取它。我做到了这一点。它也与Mscoree有关。问题是MIDL编译器会自动导入" oaidl.idl"当它遇到库声明时。因此,在您有机会对其进行任何操作之前,这些类型(Stream等)已经注入到当前的IDL上下文中。这是一个记录不完整的功能。除非你删除对IStream的硬引用(使用PVOID [*]流),否则无论你做什么都会做到底线。
忽略它。不要使用它。请改用System.Runtime.InteropServices.ComTypes.IStream。只要您使用的接口(在.Net中)标记有正确的属性(Guid,InterfaceType等),它们就是可互换的。您必须编辑类型库或互操作代码,以便它接受您希望传递的类型。我会使用对象,因此您可以使用任何IStream接口(具有有效的定义)。并且也不使用旧的TlbImp工具。使用新的TlbImp2(用C#和开源编写)https://clrinterop.codeplex.com/releases/view/17579。它允许您真正自定义从TLB到Managed的转换,除了编译的interop dll之外,您还可以生成源文件而不是/。
答案 1 :(得分:0)
这不需要修复,从类型库创建的interop包装器就可以了。 ComTypes.IStream声明允许托管代码实现实现IStream的COM服务器或将其作为参数。很多.NET框架类都可以。