我正在编写一个可以从Excel VBA访问的C ++ DLL(它只完成数学方程式,不需要从工作表中访问)。 DLL旨在取代当前的VBA代码,我想用C / C ++编写它以获得性能。
由于我正在使用现有代码并且只想用新的DLL替换当前的VBA函数,所以我必须使用包含单个向量数组的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 ++代码正确访问数组的元素(唯一的区别是SAFEARRAY
正在访问input0的地址。 / p>
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功能有什么问题?
答案 0 :(得分:2)
您应该检查VT_BYREF
标志,如果已设置,则取消引用指针以访问数组,如下所示:
pSafeArrayInput0 = *V_ARRAYREF(input0);