Как мне объявить IStream в idl, чтобы visual studio сопоставила его с s.w.interop.comtypes?

StackOverflow https://stackoverflow.com/questions/2691086

Вопрос

У меня есть COM-объект, который принимает поток от клиента C # и обрабатывает его.Казалось бы, я должен использовать IStream.Поэтому я пишу свой idl, как показано ниже.Затем я использую MIDL для компиляции в tlb и компилирую свое решение, регистрирую его, а затем добавляю ссылку на свою библиотеку в проект C #.

Visual Studio создает определение IStream в моей собственной библиотеке.Как я могу помешать ему делать это и заставить его использовать COMTypes IStream?Кажется, был бы один из 3 ответов:добавьте немного импорта

  • к idl, чтобы он не переопределял IStream (импорт MSCOREE делает это, но не решает проблему C #)
  • каким-то образом создайте псевдоним IStream в Visual studio, но я не вижу, как это сделать.
  • Все мои размышления абсолютно неверны, и я вообще не должен использовать 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;
  };

};
Это было полезно?

Решение

Это не требует фиксации, оболочка взаимодействия, созданная из библиотеки типа, будет в порядке. The Comtypes.istream Декларация должна позволить управляемому коду реализовать COM-сервер, который реализует ISTream или принимает один в качестве аргумента. Много классов .NET рамочных классов.

Другие советы

То, что вы видите и испытываете, является особенностью (часто раздражающей) компилятора MIDL.Любой тип, на который есть ссылка в разделе "библиотека", будет иметь свое определение, введенное в tlb (библиотеку типов).;за исключением интерфейса IUnknown и Базовые типы MIDL, (и, возможно, еще пара примитивных типов).Те странные методы, которые вы видите в "вашем" IStream, исходят из базового типа ISequentialStream.У вас есть несколько вариантов:

  1. Несколько дней ломайте голову над компилятором MIDL, пытаясь получить его путем внедрения IStream (и всех других поддерживающих его типов).Я сделал это.Так было и с Mscoree.Проблема в том, что компилятор MIDL автоматически импортирует "oaidl.idl", когда он встречает инструкцию library.Таким образом, эти типы (Stream и тому подобное) Уже введены в текущий контекст IDL, прежде чем у вас появится шанс что-либо с этим сделать.Это плохо документированная функция.Суть в том, что он будет делать это независимо от того, что вы делаете, если только вы не удалите жесткие ссылки на IStream (используйте PVOID [*] stream).

  2. Игнорируй это.Даже не пользуйся им.Вместо этого используйте System.Runtime.InteropServices.ComTypes.IStream.Пока используемый вами интерфейс (в .Net) помечен правильными атрибутами (Guid, InterfaceType и т.д.), они взаимозаменяемы.Вам нужно будет либо отредактировать библиотеку типов, либо код взаимодействия, чтобы он принимал тот тип, который вы хотите ему передать.Я бы выбрал object, чтобы вы могли использовать любой интерфейс IStream (с допустимым определением).А также не используйте старый инструмент TlbImp.Используйте новый TlbImp2 (написанный на C # с открытым исходным кодом) https://clrinterop.codeplex.com/releases/view/17579.Это позволяет вам действительно настроить преобразование из TLB в Managed, и вы можете заставить его создавать исходные файлы вместо / в дополнение к скомпилированной библиотеке DLL взаимодействия.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top