2010-04-22 7 views
1

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

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

}; 

ответ

0

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

+0

спасибо. Ну, так что каждый нуждается в другой оболочке для каждой библиотеки COM, которая использует IStream? Кроме того, импортированная оболочка IStream, которую я получаю, отличается от ComTypes IStream. У него даже нет таких же операций, и как вы его реализуете ?: void RemoteRead (out byte pv, uint cb, out uint pcbRead); Можете ли вы читать только один байт за раз? –

+0

Обертка - это просто объявление.Звучит для меня, что вы нашли что-то еще, а затем простой IStream. Может быть, прокси. –

+0

@HansPassant Я боюсь, что это не так (по крайней мере, в моем опыте). У меня есть несколько (C++) COM-классов, которые экспортируют функции с одним параметром, определенным как IStream, и ни один из них не возьмет объект, который реализует ComTypes.IStream, все они получают «собственное» внутреннее определение IStream и бросают объект, который реализует ComTypes .Использование этого не помогает. – yms

0

Что вы видите и испытываете, является особенностью (часто раздражающей) компилятора MIDL. Любой тип, который указан в разделе «library», будет иметь свое определение, введенное в tlb (библиотека типов); за исключением интерфейса IUnknown и MIDL base types (и, возможно, еще нескольких примитивных типов). Эти странные методы, которые вы видите на «вашем» 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.

 Смежные вопросы

  • Нет связанных вопросов^_^