How do I declare an IStream in idl so visual studio maps it to s.w.interop.comtypes?

狂风中的少年 提交于 2019-12-30 12:20:31

问题


I have a COM object that takes needs to take a stream from a C# client and processes it. It would appear that I should use IStream. So I write my idl like below. Then I use MIDL to compile to a tlb, and compile up my solution, register it, and then add a reference to my library to a C# project.

Visual Studio creates an IStream definition in my own library. How can I stop it from doing that, and get it to use the COMTypes IStream? It seems there would be one of 3 answers: add some import

  • to the idl so it doesn't redeclare IStream (importing MSCOREE does that, but doesn't solve the C# problem)
  • somehow alias the IStream in visual studio - but I don't see how to do this.
  • All my thinking i s completely wrong and I shouldn't be using IStream at all

help...thanks

[
  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;
  };

};

回答1:


This doesn't need fixing, the interop wrapper created from the type library will be fine. The ComTypes.IStream declaration is there to allow managed code to implement a COM server that implements an IStream or takes one as an argument. Lots of .NET framework classes do.




回答2:


What you are seeing and experiencing is a feature (often annoying one) of the MIDL compiler. Any type that is referenced inside the "library" section will have its definition injected into the tlb (type library); with the exception of the IUnknown interface and the MIDL base types, ( and maybe a couple more primitive types). Those weird methods you are seeing on "your" IStream are coming from the base type, ISequentialStream. You have a few options:

  1. Wrestle with the MIDL compiler for days to try to get it from injecting IStream (and all its other supporting types). I've done this. It was also with Mscoree. The problem is that the MIDL compiler automatically imports "oaidl.idl" when it encounters a library statement. So those types (Stream and such) are already injected into the current IDL context before you have a chance to do anything about it. This is a poorly documented feature. Bottom line is its going to do it no matter what you do, unless you remove the hard references to IStream (use PVOID [*] stream).

  2. Ignore it. Don't even use it. Use System.Runtime.InteropServices.ComTypes.IStream instead. As long as the interface you are using (in .Net) is marked with the correct attributes (Guid, InterfaceType, etc), they are interchangeable. You'll have to either edit the type library or interop code so it will accept what type you wish to pass it. I'd go with object so you can use any IStream interface (with a valid definition). And also don't use the old TlbImp tool. Use the new TlbImp2 (written in C# and open source) https://clrinterop.codeplex.com/releases/view/17579. It allows you to really customize the conversion from TLB to Managed and you can have it produce source files instead of/in addition to a compiled interop dll.



来源:https://stackoverflow.com/questions/2691086/how-do-i-declare-an-istream-in-idl-so-visual-studio-maps-it-to-s-w-interop-comty

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!