.NET реализация интерфейса C ++, доступ к COM - PullRequest
1 голос
/ 09 ноября 2011

Я уверен, что ответом на мою проблему является сочетание множества тем, уже присутствующих на этом форуме.Может быть, вы можете помочь мне собрать все воедино.

Итак, моя проблема в том, что у меня есть некоторый код C ++, который реализует интерфейс, который выглядит следующим образом:

interface ItsSupplier : IDispatch {
    [propget, id(1), helpstring("property name") HRESULT Name([out, retval] BSTR* pVal);
}

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

Вот как я это делаю в .NET.

[Guid("xxxx")]
public interface ItsSupplier {
    [DispId(1)]
    [return: MarshalAs(UnmanagedType.Bstr)]
    string Name { get; }
}

[Guid("xxxx"),
ClassInterface(ClassInterfaceType.AutoDispatch),
ComSourceInterfaces(typeof(ItsSupplier))]
    public class SupplierClass : ItsSupplier
    {
        public string { get { return "someName"; } }
    }
}

ПодВ настройках проекта я проверил «Зарегистрироваться для COM-взаимодействия».

После сборки я запускаю «regasm testDll.dll»

Мои вопросы ...

Этоправильный способ определить интерфейс ItsSupplier самостоятельно?Я имею в виду, что это интерфейс, который ожидает стороннее программное обеспечение, поэтому на него придется ссылаться где-то еще?

Правильно ли я делаю это, когда дело касается взаимодействия COM?

Я надеюсь, что я объясняю это право:)

Приветствия / Томас

---------------- РЕДАКТИРОВАТЬ ПОСЛЕ ОТВЕТА ОТ ГАНСА ------------------------

Когда я собираю файл tlb и просматриваю оригинал и мою версию в Oleview, это то, что я получаю.

Вот как выглядит оригинальный интерфейсный плагин в Oleview:

[
  odl,
  uuid(370B4079-40BB-47C9-B797-33B3B5422685),
  helpstring("ItsSupplier Interface"),
  dual,
  oleautomation
]
interface ItsSupplier : IDispatch {

Вот как выглядит мой:

[
  odl,
  uuid(370B4079-40BB-47C9-B797-33B3B5422685),
  version(1.0),
  dual,
  oleautomation,
  custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "COMDLL.ItsSupplier")    

]
interface COMDLL_ItsSupplier : IDispatch {

"COMDLL" - это имямой визуальный студийный проект.Как вы думаете, это имеет значение?

/ Томас

1 Ответ

3 голосов
/ 09 ноября 2011

Нет, множество мелких ошибок, которые могут привести к неприятностям.Во-первых, интерфейс c ++ объявляет двойной интерфейс, поддерживающий как раннее, так и позднее связывание через IDispatch.Вы должны использовать атрибут [InterfaceType] в .NET, чтобы получить то же самое:

[ComVisible(true)]
[Guid("xxxx")]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ItsSupplier {
    [DispId(1)]
    string Name { get; }
}

Обязательно используйте точный такой же guid, он не был виден в вашем фрагменте.Атрибут [MarshalAs] не нужен, строка уже маршалирует как BSTR.

Далее идет класс.Вы не хотите раскрыть реализацию класса.Это заставляет код клиента также остерегаться System.Object, базового класса всех классов .NET.Он появится в библиотеке типов.Использование [ComSourceInterfaces] некорректно, его следует применять только к dispinterfaces для событий.

[ComVisible(true)]
[Guid("xxxx")]
[ClassInterface(ClassInterfaceType.None)]
public class SupplierClass : ItsSupplier
{
    public string Name {
        get { return "someName"; }
    }
}

Снова используйте точный такой же guid, как и в файле IDL.Далее идет регистрация.Использовать опцию «Зарегистрироваться для взаимодействия с COM» можно, но затем , а не , снова запустите Regasm.exe.Вы перепутаете регистрацию с этим.Если вы предпочитаете регистрироваться вручную, всегда используйте параметр / codebase, чтобы сборку не нужно было устанавливать в GAC.

Конечная проверка того, что вы все сделали правильно, - это создать библиотеку типов сTlbexp.exe и просмотреть его с помощью Oleview.exe, File + View Typelib.Это должно быть точное совпадение с вашим IDL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...