Тип SAFEARRAY неизвестен при компиляции с использованием MIDL

Мой файл ODL выглядит так:

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

[oleautomation, uuid(/* redacted */)]
interface ISomething : IUnknown
{
    HRESULT DoSomething(
        [in]BSTR User,
        [in]VARIANT Object,
        [in]SAFEARRAY Array         // may be NULL
        );
}

Я получаю ошибки:

1>. \ Something.odl (17): ошибка MIDL2139: тип параметра не может быть производным от void или void *: [Введите 'PVOID' (параметр 'Array')] 1>. \ Something.odl (17): ошибка MIDL2105: указатель / массив не определяет размер: [Поле 'rgsabound' структуры 'tagSAFEARRAY' (параметр 'Массив')] 1>. \ Something.odl (17): ошибка MIDL2465: Структуры, содержащие соответствующие массивы, должны передаваться ссылка. Дополнительные сведения см. В MSDN: [Struct 'tagSAFEARRAY' (параметр 'Array')]

Если я изменю тип с SAFEARRAY на SAFEARRAY* (что я не считаю правильным?), Я получаю разные ошибки:

1>. \ Something.odl (17): ошибка MIDL2139: тип параметра не может быть производным от void или void *: [Введите 'PVOID' (параметр 'Array')] 1>. \ Something.odl (17): ошибка MIDL2105: указатель / массив не определяет размер: [Поле 'rgsabound' структуры 'tagSAFEARRAY' (параметр 'Массив')]

Это просто случай, когда мне нужно включить другие заголовки? Я компилирую с помощью компилятора MIDL в VS2013, видимо, командная строка выглядит так:

/iid "./source/Something_i.c" /h "Something.h" /W1 /char signed /notlb /app_config /nologo /dlldata "./source/Something_dlldata.c" /proxy "./source/Something_p.c" 

person Mr. Boy    schedule 19.10.2015    source источник
comment
Вам нужно указать, какие типы элементов находятся в вашем SafeArray. Например, SAFEARRAY (unsigned char) * Данные для массива беззнаковых символов. Если тип данных элементов массива является переменным во время выполнения, вы можете передать элементы как SafeArray типа VARIANT.   -  person JJF    schedule 19.10.2015
comment
@JJF Я только что узнал об этом и собирался ответить на свой вопрос ... если вы можете добавить это в качестве ответа (в идеале исправляя мои сигнатуры методов), я с радостью приму это.   -  person Mr. Boy    schedule 19.10.2015


Ответы (1)


Вам нужно указать, какие типы элементов находятся в вашем SafeArray. Например, SAFEARRAY (unsigned char) * Данные для массива беззнаковых символов. Если тип данных элементов массива является переменным во время выполнения, вы можете передать элементы как SafeArray типа VARIANT. Например:

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

[oleautomation, uuid(/* redacted */)]
interface ISomething : IUnknown
{
    HRESULT DoSomething(
        [in]BSTR User,
        [in]VARIANT Object,
        [in]SAFEARRAY(unsigned char) *Array         // may be NULL
        );
}
person JJF    schedule 19.10.2015
comment
Моя проблема заключалась в указании типа содержимого, спасибо. Однако, когда я указываю SAFEARRAY *, мой сгенерированный файл заголовка выглядит как /* [in] */ SAFEARRAY * *Array, что не очень хорошо! - person Mr. Boy; 19.10.2015
comment
Не уверен, почему это проблема. Я не уверен, что вы вообще можете передать SAFEARRAY по значению. Что сказал компилятор midl, когда вы опустили '*'? Все это означает, что вам нужно добавить дополнительное разыменование, чтобы получить доступ к данным. - person JJF; 19.10.2015
comment
Если я указываю в IDL по значению, заголовок C ++ автоматически ссылается на него по указателю. Я предполагаю, что маршаллинг .net будет просто иметь тип массива. - person Mr. Boy; 19.10.2015
comment
У меня нет большого опыта в выборе управляемого и неуправляемого кода. То, что я делал с COM, было очень давно ... - person JJF; 19.10.2015
comment
В любом случае, это кажется второстепенным вопросом, возможно, это требует нового вопроса, но ваш ответ решает мою исходную проблему! - person Mr. Boy; 19.10.2015
comment
Удаление SAFEARRAY (type) уже подразумевает один уровень косвенности. Итак, [входящие] параметры - это [in] SAFEARRAY(type) v (который передается как SAFEARRAY *), а [выходящие] параметры - это [out] SAFEARRAY(type) * v (который передается как SAFEARRAY **) - person peterchen; 09.04.2020