Как мне объявить IStream в idl, чтобы Visual Studio отображала его на s.w.interop.comtypes? - PullRequest
1 голос
/ 22 апреля 2010

У меня есть 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;
  };

};

Ответы [ 2 ]

1 голос
/ 24 сентября 2014

То, что вы видите и испытываете, является функцией (часто раздражающей) компилятора 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 в Managed, и вы можете создать исходные файлы вместо / в дополнение к скомпилированному dll взаимодействия.

0 голосов
/ 22 апреля 2010

Это не нуждается в исправлении, оболочка взаимодействия, созданная из библиотеки типов, будет в порядке. Объявление ComTypes.IStream позволяет управляемому коду реализовать COM-сервер, который реализует IStream или принимает его в качестве аргумента. Многие классы .NET Framework делают.

...