将动态分配的数组从C DLL返回到VBA

Return a dynamically allocated array from C++ dll to VBA

本文关键字:DLL 返回 VBA 动态分配 数组      更新时间:2023-10-16

免责声明:i 知道如何在VBA中分配内存,在C dll中填充数组并返回其指针,但可悲的是我可能会发现一些我不知道数组大小的情况,因此在将其传递给DLL之前,我将无法在VBA中进行DimReDim

假设我的DLL内有一个C 子例程,它将"返回"两件事作为输出:一个是整数,另一个是一个数组:

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" outWeight_Coeff数组中C 中的情况。有可能这样做吗?

编辑:我尝试和失败的其他方式:

而不是使用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(中,并/或创建一个新数组并替换参数中传递的任何数组。

使用ATL类CComVariantCComSafeArray<double>实现的最简单方法。不要忘记将附件/分离用于ccomvariant,否则您可能会泄漏内存。

不幸的是,如果您没有C 中COM自动化的经验,即使在ATL实用程序类中,您也会花一些时间来实现:附加/分离,VT_BYREF,不同的下限等,对于一个相对繁琐的2D数组。