Excel VBA からアクセスする C++ DLL を作成しています (数式を完了するだけで、ワークシートからアクセスする必要はありません)。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
配列を usingに変換した後に配列の内容を読み取ろうとすると、問題が発生し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;
}
私が見つけたすべての例は、ポインターによる入力の受け渡しが私の ReadArrayByRef 関数ごとに機能することを示していVARIANT
ます)。
ByRef 関数で何が間違っていますか?