Как создать и инициализировать SAFEARRAY удвоений в С++ для перехода на С#
Мой С# метод должен быть вызван из С++
Первоначально мой метод С# принимает параметр типа double [], но при вызове из С++ он становится SAFEARRAY
В С++ мне нужно взять данные из массива двойников и заполнить SAFEARRAY. Я не нашел код примера для этого.
Любая помощь приветствуется
Ответы
Ответ 1
Ниже приведен код для создания safearray в С++.
#include<oaidl.h>
void CreateSafeArray(SAFEARRAY** saData)
{
double data[10]; // some sample data to write into the created safearray
SAFEARRAYBOUND Bound;
Bound.lLbound = 0;
Bound.cElements = 10;
*saData = SafeArrayCreate(VT_R8, 1, &Bound);
double HUGEP *pdFreq;
HRESULT hr = SafeArrayAccessData(*saData, (void HUGEP* FAR*)&pdFreq);
if (SUCCEEDED(hr))
{
// copy sample values from data[] to this safearray
for (DWORD i = 0; i < 10; i++)
{
*pdFreq++ = data[i];
}
SafeArrayUnaccessData(*saData);
}
}
Освободите указатель, когда вы закончите, как следующий код -
SAFEARRAY* saData;
CreateSafeArray(&saData); // Create the safe array
// use the safearray
...
...
// Call the SafeArrayDestroy to destroy the safearray
SafeArrayDestroy(saData);
saData = NULL; // set the pointer to NULL
Если вы используете ATL для С++, тогда лучше использовать CComSafeArray, объявленный в "atlsafe.h". Это оболочка для SAFEARRAY. текст ссылки
Ответ 2
Продолжая отвечать на @Liton, я хочу подчеркнуть его последнее предложение, т.е. ATL CComSafeArray
. Это действительно может сэкономить вам много набрав. CComSafeArray
имеет конструкторы С++, деструкторы, перегрузки операторов, в том числе один для [], который дает ссылку на чтение/запись любому элементу в SAFEARRAY
. Короче говоря, вы можете сосредоточиться на своей бизнес-логике и не беспокоиться о сантехнике SAFEARRAY
:
#include <atlbase.h>
#include <atlsafe.h>
// ...
CComSafeArray<double> arr(10);
arr[0] = 2.0;
arr[1] = 3.0;
arr[2] = 5.0;
// ...
По крайней мере, даже если вы не собираетесь использовать CComSafeArray
, стоит деконструировать его исходный код в <atlsafe.h>
, чтобы лучше понять функции what, when, why and how on SAFEARRAY
.
Ответ 3
Передача SAFEARRAY не рекомендуется. Рекомендуется помещать SAFEARRAY в VARIANT. Кроме того, SAFEARRAY должен хранить данные VARIANT. Это дает лучшее из всех миров и делает переход VARIANT SAFEARRAY of VARIANT более полезным для других языков. Например. С++ для VB/С# (обратите внимание, что до вызывающего абонента освобождается/уничтожает SAFEARRAY)
Основываясь на предыдущем коде
// A VARIANT holding a SAFEARRAY of VARIANTs
VARIANT vRet;
SAFEARRAYBOUND Bound;
Bound.lLbound = 0;
Bound.cElements = 10;
SAFEARRAY * psaData = SafeArrayCreate(VT_VARIANT, 1, &Bound);
VARIANT HUGEP * pData = NULL;
HRESULT hr = SafeArrayAccessData(psaData, (void HUGEP * FAR *)&pData);
if (SUCCEEDED(hr))
{
for (short i = 0; i < 10; ++i,++pData)
{
::VariantInit(pData);
pData->vt = VT_I2;
pData->iVal = i;
}
SafeArrayUnaccessData(psaData);
}
vRet.vt = VT_ARRAY | VT_VARIANT;
vRet.parray = psaData;