Как я могу использовать пользовательский тип (UDT) на COM-сервере? - PullRequest
1 голос
/ 23 апреля 2009

У меня есть COM-сервер с методом, который в настоящее время возвращает целое число:

[
    object,
    uuid("..."),
    dual,
    helpstring("IMyCOMServer Interface"),
    pointer_default(unique)
]
__interface IMyCOMServer : IDispatch
{
    [id(1), helpstring("method MyQuery")]
    HRESULT MyQuery([in] BSTR instr, [out,retval] int* outint);
};

Это прекрасно компилируется, но я бы лучше вернул перечисление: (этот код на самом деле выше определения интерфейса)

typedef
[
    uuid("..."),
    v1_enum,
    helpstring("Enum")
]
enum {
    value_a,
    value_b,
    value_c
} MyEnum;

, который снова сам компилируется нормально, но как только я изменяю int* на MyEnum* в интерфейсе и реализации, я получаю ошибки компоновщика:

[id(1), helpstring("method MyQuery")]
HRESULT MyQuery([in] BSTR instr, [out,retval] MyEnum* outint);

error MIDL2025 : syntax error : expecting a type specification near "MyEnum"

Какой бы способ я ни делал, я не могу заставить его скомпилироваться.


Благодаря Euro Micelli выясняется, что реальная проблема заключается в том, что мой пользовательский тип (перечисление) не попал в сгенерированный файл .IDL. Судя по форумным запросам в Интернете, это, кажется, общая проблема.

Статья в блоге Star Tech: UDT (определяемые пользователем типы) и COM указали мне правильный путь. Похоже, что обходной путь необходим при использовании атрибутивной ATL.

В итоге я внес следующие изменения:

Создано udt.idl:

import "oaidl.idl";
import "ocidl.idl";

[
    uuid("..."),
    v1_enum,
    helpstring("Enum")
]
typedef enum MyEnum {
    value_a,
    value_b,
    value_c
} MyEnum_t;

[
    version(1.0),
    uuid(...),
    helpstring(...)
]
library MyLibrary
{
    enum MyEnum;
}

Добавлена ​​следующая строка перед атрибутом модуля в основном файле .cpp, чтобы вышеуказанный IDL был импортирован в сгенерированный файл:

[importidl("udt.idl")];

Ответы [ 3 ]

1 голос
/ 24 апреля 2009

Вы почти получили его, но компилятор idl имеет более строгий синтаксис, чем cl.exe. Вам нужно иметь начальное имя перечисления перед перечислением вот так.

typedef
[uuid("..."), v1_enum, helpstring("Enum")]
enum tagMyEnum
{
    value_a,
    value_b,
    value_c
} MyEnum;

Если вы создаете и регистрируете свой tlb, языки сценариев должны иметь доступ к вашему enum в сценариях и .NET.

1 голос
/ 25 апреля 2009

(Это адаптировано из фактического IDL, так что я знаю, что это работает)

[uuid(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX), v1_enum, helpstring("Enum")]
enum MyEnum {
    value_a,
    value_b,
    value_c
} ;

Кроме того, в разделе «Библиотека» вы также должны включить перечисление, иначе перечисление не будет экспортировано в библиотеку типов:

library MyLib
{
    enum MyEnum;
...
};
1 голос
/ 24 апреля 2009

Это очень зависит от компилятора, поскольку перечисления не имеют фиксированного размера хранилища.

Существует также угол совместимости - как бы вы представили это перечисление, скажем, в Visual Basic или C #? Базовое хранилище представляет собой целое число, так что это то, что позволяет COM.

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