Классы COM отображаются в виде пустой структуры на стороне C # с включенной поддержкой / clr - PullRequest
1 голос
/ 22 февраля 2011

Ранее я использовал tlbimp.exe в событии после сборки для генерации управляемой сборки взаимодействия для собственного проекта C ++ COM.

Я хочу напрямую ссылаться на проект c ++ из проекта, управляемого C #.

Я изменил проект C ++ для поддержки Common Language Runtime Support т.е. / clr

После того, как я удалил старую ссылку на взаимодействие на стороне C # и добавил ссылку на проект C ++, интерфейсы и классыотображаются как пустые статические структуры.

Сторона C ++:


// IRow
[
    object,
    uuid("2D52A372-1094-4A59-AF6B-A874E587FA98"),
    dual,   helpstring("IRow Interface"),
    pointer_default(unique)
]
public __interface IRow : IDispatch
{
  [id(DISPID_VALUE), helpstring("method Item")]
    HRESULT Item([in] LONG index, [out,retval] VARIANT* val);
};

Сторона C # [из метаданных]:


[CLSCompliant (false)]
[NativeCppClass]
public static struct IRow
{
}

Есть какие-нибудь намеки на то, чего не хватает?

1 Ответ

3 голосов
/ 24 февраля 2011
Интерфейс

__ является частью набора языковых расширений (называемых «атрибутами»), представленных в Visual Studio 2002. Цель заключалась в том, чтобы иметь возможность напрямую определять исходный код C ++, что вы обычно определяете в MIDL, и облегчать использование ATL.автоматически создавая атрибуты "grok".

Когда вы собираете исходный код C ++ без / clr и используете tlbimp для импорта сгенерированной библиотеки типов, IRow определяется в сборке взаимодействия, сгенерированной tlbimp.Его определение полностью основано на библиотеке типов COM, созданной с использованием __interface;то есть это обычный интерфейс .NET с атрибутом ComImport.

Когда вы создаете исходный код C ++ с помощью / clr, компилятор C ++ генерирует метаданные .NET для IRow, чтобы обозначить, что это собственный тип, поскольку он остается интерфейсом COM даже при применении / clr.Чтобы правильно использовать IRow из C #, вы должны либо продолжать использовать IRow из сборки взаимодействия, созданной с помощью tlbimp (или вручную), либо преобразовать IRow (и классы, которые его реализуют) в типы .NET, используя C ++ / CLI.В качестве альтернативы, вы можете определить некоторые классы-обертки в C ++ / CLI, которые напрямую используют типы COM, но я не вижу большого преимущества в этом.

Вот как может выглядеть интерфейс и разработчик в C ++/ CLI:

public interface class IRow
{
    System::Object^ Item(int index);
};

public ref class ImplementedRow : public IRow
{
public:
   System::Object^ Item(int index) { return nullptr; }
};

Я подозреваю, что это не может быть тривиальной перепиской для ваших существующих объектов COM, поэтому я, вероятно, просто придерживаюсь COM-взаимодействия, если у вас нет веских причин не делать этого.

...