Не удается преобразовать массив ByRef VARIANT в SAFEARRAY

Я пишу C ++ DLL для доступа из Excel VBA (она только дополняет математические уравнения и не требует доступа к рабочему листу). DLL предназначена для замены текущего кода VBA, и я хочу написать его на C / C ++ для повышения производительности.

Поскольку я использую существующий код и просто хочу заменить текущую функцию VBA новой DLL, я должен использовать варианты VBA, содержащие одиночные векторные массивы. Ниже приведен сокращенный пример кода вызова VBA:

Sub VBACaller()
Dim InputR0(1 To 5) As Variant, vResult As Variant

InputR0(1) = 26.8
InputR0(2) = 27.8
InputR0(3) = 28.8
InputR0(4) = 29.8

vResult = ReadArrayVBA(InputR0)
End Sub

Я могу передать этот массив Variant моей функции C ++ либо ByVal или же ByRef как VARIANT Тип данных, и он, кажется, был получен правильно. Мои проблемы возникают, когда я пытаюсь прочитать содержимое массива после преобразования его в SAFEARRAY с помощью SafeArrayAccessData, SAFEARRAY кажется, что преобразование работает, но содержимое массива неверно. Вот мой код на C ++:

VARIANT __stdcall ReadArrayByRef(VARIANT *input0)
{
//Variable to assign value from Array
double d_m = 0;

//Check if this is a variant type or not
if (V_VT(input0) & VT_ARRAY)
{
SAFEARRAY* pSafeArrayInput0 = NULL;
pSafeArrayInput0 = V_ARRAY(input0);

double* pVals;

HRESULT hr = SafeArrayAccessData(pSafeArrayInput0, (void **)&pVals); // direct access to SA memory
if (SUCCEEDED(hr))
{
long lLBound = -1, lUBound = 1;  // get array bounds
SafeArrayGetLBound(pSafeArrayInput0, 1, &lLBound);
SafeArrayGetUBound(pSafeArrayInput0, 1, &lUBound);

if (lLBound > -1 && lUBound > -1)
{
d_m =  pVals[1];
}
SafeArrayUnaccessData(pSafeArrayInput0);
}
}

//Output
VARIANT v;
VariantInit(&v);
v.vt = VT_R8;
v.dblVal = d_m;

return v;
}

Примеры, которые я нашел, показывают, что .parray должны содержать данные, однако осмотр input0 указывает, что это в .pparray, Если я попытаюсь назначить pSafeArrayInput0 = input0.pparray это дает ошибку. Значение d_m возвращается по линии 1.05319234616515E-307,

Если я изменю ввод на ByVal тогда я могу получить доступ к элементам массива правильно, используя следующий код C ++ (единственное отличие состоит в том, что адрес input0 доступен через SAFEARRAY,

VARIANT __stdcall ReadArrayByVal(VARIANT input0)
{
//Variable to assign value from Array
double d_m = 0;

//Check if this is a variant type or not
if (V_VT(&input0) & VT_ARRAY)
{
SAFEARRAY* pSafeArrayInput0 = NULL;
pSafeArrayInput0 = V_ARRAY(&input0);

double* pVals;

HRESULT hr = SafeArrayAccessData(pSafeArrayInput0, (void **)&pVals); // direct access to SA memory
if (SUCCEEDED(hr))
{
long lLBound = -1, lUBound = 1;  // get array bounds
SafeArrayGetLBound(pSafeArrayInput0, 1, &lLBound);
SafeArrayGetUBound(pSafeArrayInput0, 1, &lUBound);

if (lLBound > -1 && lUBound > -1)
{
d_m =  pVals[1];
}
SafeArrayUnaccessData(pSafeArrayInput0);
}
}

VARIANT v;
VariantInit(&v);
v.vt = VT_R8;
v.dblVal = d_m;

return v;
}

Все примеры, которые я нашел, показывают, что прохождение VARIANT ввод с помощью указателя должен работать для моей функции ReadArrayByRef (т.е. http://support.microsoft.com/kb/167668 что немного отличается, но то же самое в точках, которые я после).

Что я делаю не так в своей функции ByRef?

1

Решение

Вы должны проверить VT_BYREF флаг, и если он установлен, разыменуйте указатель для доступа к массиву следующим образом:

pSafeArrayInput0 = *V_ARRAYREF(input0);
2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]