SAFEARRAY как средство возврата массива
От: AlexGin Беларусь  
Дата: 16.07.18 05:21
Оценка:
Доброе время суток, уважаемые коллеги!

Я сделал COM In-Process сервер (в виде DLL).
Эта штука на C++ делает некоторую вычислительную работу, а массив результатов должен вернуться в головное приложение.

Мне хотелось бы использовать SAFEARRAY — как средство возврата массива.

Для этого, метод (или свойство "get") должно иметь [out] параметр вида:

    [propget, id(7)] HRESULT Array1([out, retval] SAFEARRAY** pVal);


Вот рекомендации:
https://msdn.microsoft.com/en-us/magazine/mt795188.aspx

Метод заполнения массива должен выглядеть примерно так:
STDMETHODIMP CMyComComponent::DoSomething(/* [out] */ SAFEARRAY** ppsa) noexcept
{
  try
  {
    // Create a safe array storing 'count' BYTEs
    const LONG count = /* some count value */;
    CComSafeArray<BYTE> sa(count);
    // Fill the safe array with some data
    for (LONG i = 0; i < count; i++)
    {
      sa[i] = /* some value */;
    }
    // Return ("move") the safe array to the caller
    // as an output parameter
    *ppsa = sa.Detach();
  }
  catch (const CAtlException& e)
  {
    // Convert ATL exceptions to HRESULTs
    return e;
  }
  // All right
  return S_OK;
}



Проблема — в том, что MIDL компилятор всё время ругается, на попытку компиляции вышеуказанного свойства propget, id(7)] HRESULT Array1... :

AlexGinTest1.idl(25): error MIDL2139: type of the parameter cannot derive from void or void * : [ Type 'PVOID' ( Parameter 'pVal' ) ]
AlexGinTest1.idl(25): error MIDL2105: pointee / array does not derive any size : [ Field 'rgsabound' of Struct 'tagSAFEARRAY' ( Parameter 'pVal' ) ]


Просматривал ссылочки на материалы по применению SAFEARRAY:
https://blogs.msmvps.com/gdicanio/2011/02/04/simplifying-safearray-programming-with-ccomsafearray
https://www.codeproject.com/Articles/2452/Passing-C-Object-in-ATL-DLL-Server

Но понять, как решить данную проблему пока невозможно.

Какие есть мысли по этому поводу?

P.S. Попытки сделать предоставление массива клиентом, с заполнением на сервере (и дальнейшем использовании-освобождении на клиенте),
и методы доступа по типу:

    [id(7)] HRESULT SetSafeArray([in] SAFEARRAY(byte)** ptrArr);
    [id(8)] HRESULT GetSafeArray([out] SAFEARRAY(byte)** ptrOutArr);


Проходят через MIDL компилятор, но срезаются ошибками C++ компиляции:

Error C2259 'ATL::CComObject<T>': cannot instantiate abstract class AlexGinTest1 c:\program files (x86)\microsoft visual studio 14.0\vc\atlmfc\include\atlcom.h 2000

Отредактировано 16.07.2018 7:33 AlexGin . Предыдущая версия . Еще …
Отредактировано 16.07.2018 5:43 AlexGin . Предыдущая версия .
Отредактировано 16.07.2018 5:26 AlexGin . Предыдущая версия .
Отредактировано 16.07.2018 5:23 AlexGin . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.