Return 从 C++ dll 到 VBA 的动态分配数组
Return a dynamically allocated array from C++ dll to VBA
免责声明:我知道如何在VBA中分配内存,填充C++ DLL中的数组和return它的指针,但是 可悲的是,我可能会发现一些我不知道数组大小的情况,因此我无法 Dim
或 ReDim
它在 VBA,然后将其传递给 DLL。
假设我的 DLL 中有一个 C++ 子例程,它将 "return" 输出两件事:一个是整数,另一个是数组:
void _stdcall mySub(int inOption, int outXPR, double* outWeight_Coeff)
// Do Stuff
WindowThetaHalf = [insert random value here];
WindowPhiHalf = [insert random value here];
outXPR = value;
outWeight_Coeff = new double[(WindowThetaHalf + 1) * (WindowPhiHalf + 1)];
for (int i = -WindowThetaHalf; i <= WindowThetaHalf; i++)
{
for (int j = -WindowPhiHalf; j <= WindowPhiHalf; j++)
{
outWeight_Coeff[i + WindowThetaHalf + j * (WindowThetaHalf + 1) * 2 + WindowPhiHalf] = i + j;
}
}
现在,我知道我必须将数组的第一个元素作为指针提供给 DLL 才能使其正常工作:
Private Declare Sub mySub Lib "[dll path here]" (ByVal inOption As Long, ByVal XPR As Long, ByRef outWeight_Coeff As Double)
Sub main()
Dim XPR As Long
Dim a() As Double
ReDim a(0, 0)
LoadChannelType 1, XPR, a(0, 0)
Debug.Print XPR
For i = 0 To UBound(a, 1)
For j = 0 To UBound(a, 2)
Debug.Print a(i, j)
Next
Next
End Sub
虽然这不起作用。我觉得这可能与我在 VBA 中指定的维度有关,但同样,我很可能不得不处理我基本上必须“ReDim
" C++ 中的 outWeight_Coeff
数组。
有没有可能这样做?
编辑:我尝试过但失败的其他方法:
我还尝试了以下方法,而不是使用 new
:
使用malloc
:
outWeight_Coeff = (double*)malloc(((WindowThetaHalf + 1) * (WindowPhiHalf + 1)) * sizeof(double));
正在创建一个新数组并将指针分配给它:
double* newArr = new double [(WindowThetaHalf + 1) * (WindowPhiHalf + 1)];
outWeight_Coeff = newArr;
C++ 原型:
void __stdcall mySub(int inOption, int outXPR, VARIANT *outWeight_Coeff)
VBA原型:
Private Declare Sub mySub Lib "[dll path here]" (ByVal inOption As Long, ByVal XPR As Long, ByRef outWeight_Coeff As Variant)
此方法允许您在 C++ (SafeArrayRedim) 中调整数组的大小,and/or 创建一个新数组并替换参数中传递的任何数组。
最简单的实现方法是使用 ATL 类 CComVariant
和 CComSafeArray<double>
。不要忘记为 CComVariant 使用 Attach/Detach,否则可能会泄漏内存。
不幸的是,如果您没有使用 C++ 进行 COM 自动化的经验,即使使用 ATL 实用程序,您也将花费一些时间来实现它 类:Attach/Detach,VT_BYREF,不同的下界等等,对于二维数组来说比较麻烦
免责声明:我知道如何在VBA中分配内存,填充C++ DLL中的数组和return它的指针,但是 可悲的是,我可能会发现一些我不知道数组大小的情况,因此我无法 Dim
或 ReDim
它在 VBA,然后将其传递给 DLL。
假设我的 DLL 中有一个 C++ 子例程,它将 "return" 输出两件事:一个是整数,另一个是数组:
void _stdcall mySub(int inOption, int outXPR, double* outWeight_Coeff)
// Do Stuff
WindowThetaHalf = [insert random value here];
WindowPhiHalf = [insert random value here];
outXPR = value;
outWeight_Coeff = new double[(WindowThetaHalf + 1) * (WindowPhiHalf + 1)];
for (int i = -WindowThetaHalf; i <= WindowThetaHalf; i++)
{
for (int j = -WindowPhiHalf; j <= WindowPhiHalf; j++)
{
outWeight_Coeff[i + WindowThetaHalf + j * (WindowThetaHalf + 1) * 2 + WindowPhiHalf] = i + j;
}
}
现在,我知道我必须将数组的第一个元素作为指针提供给 DLL 才能使其正常工作:
Private Declare Sub mySub Lib "[dll path here]" (ByVal inOption As Long, ByVal XPR As Long, ByRef outWeight_Coeff As Double)
Sub main()
Dim XPR As Long
Dim a() As Double
ReDim a(0, 0)
LoadChannelType 1, XPR, a(0, 0)
Debug.Print XPR
For i = 0 To UBound(a, 1)
For j = 0 To UBound(a, 2)
Debug.Print a(i, j)
Next
Next
End Sub
虽然这不起作用。我觉得这可能与我在 VBA 中指定的维度有关,但同样,我很可能不得不处理我基本上必须“ReDim
" C++ 中的 outWeight_Coeff
数组。
有没有可能这样做?
编辑:我尝试过但失败的其他方法:
我还尝试了以下方法,而不是使用 new
:
使用
malloc
:outWeight_Coeff = (double*)malloc(((WindowThetaHalf + 1) * (WindowPhiHalf + 1)) * sizeof(double));
正在创建一个新数组并将指针分配给它:
double* newArr = new double [(WindowThetaHalf + 1) * (WindowPhiHalf + 1)]; outWeight_Coeff = newArr;
C++ 原型:
void __stdcall mySub(int inOption, int outXPR, VARIANT *outWeight_Coeff)
VBA原型:
Private Declare Sub mySub Lib "[dll path here]" (ByVal inOption As Long, ByVal XPR As Long, ByRef outWeight_Coeff As Variant)
此方法允许您在 C++ (SafeArrayRedim) 中调整数组的大小,and/or 创建一个新数组并替换参数中传递的任何数组。
最简单的实现方法是使用 ATL 类 CComVariant
和 CComSafeArray<double>
。不要忘记为 CComVariant 使用 Attach/Detach,否则可能会泄漏内存。
不幸的是,如果您没有使用 C++ 进行 COM 自动化的经验,即使使用 ATL 实用程序,您也将花费一些时间来实现它 类:Attach/Detach,VT_BYREF,不同的下界等等,对于二维数组来说比较麻烦