如何从C ++ DLL返回的指针中获取VBA中的整个矩阵?

时间:2017-04-25 07:37:47

标签: c++ arrays vba matrix dll

我在C ++中编写了一段代码,用于从VBA获取一个数组作为输入,并创建一个新的代码,然后将其返回给VBA。

DLL .h编写如下:

// FieldTrans.h
#ifdef FIELDTRANS_EXPORTS
#define FIELDTRANS_API __declspec(dllexport)
#else
#define FIELDTRANS_API __declspec(dllimport)
#endif

extern "C"
{
    // Returns the normalized cardinal sinus coefficient
    FIELDTRANS_API double _stdcall SinC(double x);
    // Returns the interpolated field matrix: 180° x 360° with Res step
    FIELDTRANS_API double _stdcall ShannonInterp(double** Matrix[], int MatrixHeight, int MatrixWidth, double Res, double DeltaTheta, double DeltaPhi);
};

.cpp文件:

// FieldTrans.cpp
#include "stdafx.h"
#include "FieldTrans.h"
#include <math.h>
#include <vector>

double _stdcall SinC(double x)
{
    double y;
    y = 1;
    if (x != 0)
    {
        y = sin(3.14159265358979323846 * x) / (3.14159265358979323846 * x);
    }
    return y;
}

double** _stdcall ShannonInterp(double** Matrix, int MatrixHeight, int MatrixWidth, double Res, double DeltaTheta, double DeltaPhi)
{
    int k, l, m, n;
    double iRes, jRes;
    double ThetaSinC, PhiSinC;
    int Height = static_cast<int> (180 / Res);
    int Width = static_cast<int> (360 / Res);
    double** Interpolated = new double*[Height];
    k = 0;
    m = 1;

    for (int i = 0; i < Height; i++)
    {
        Interpolated[i] = new double[Width];
        iRes = i * Res;
        do
        {
            k = k + 1;
            m = k + 1;
        } while (iRes >(k + 1) * DeltaTheta);
        if (m > MatrixHeight)
        {
            m = MatrixHeight - 1;
        }
        ThetaSinC = SinC((iRes - k * DeltaTheta) / DeltaTheta);
        l = 0;
        n = 1;
        for (int j = 0; j < Width; j++)
        {
            jRes = j * Res;
            do
            {
                l = l + 1;
                n = l + 1;
            } while (jRes >(l + 1) * DeltaPhi);
            if (n > MatrixWidth)
            {
                n = 0;
            }
            PhiSinC = SinC((jRes - l * DeltaPhi) / DeltaPhi);
            Interpolated[i][j] = 1 * ThetaSinC * PhiSinC + 2 * ThetaSinC * (1 - PhiSinC) + 3 * (1 - ThetaSinC) * PhiSinC + 4 * (1 - ThetaSinC) * (1 - PhiSinC);
        }
    }
    return Interpolated;
}

在.def文件中定义了调用名后,我在我的VBA代码上写了以下声明来调用其中一个函数:

Private Declare Function ShannonInterp Lib "C:\NSI2000\Script\FieldTrans.dll" (ByRef Matrix() As Double, ByVal MatrixHeight As Integer, ByVal MatrixWidth As Integer, ByVal Res As Double, ByVal DeltaTheta As Double, ByVal DeltaPhi As Double) As Double

我可以使用这样的功能而不会出现任何崩溃或错误:

PointerCo = ShannonInterp(AmplCo, PointsTheta, PointsPhi, Resolution, 181 / (PointsTheta+1), 361 / (PointsPhi+1))

我的问题是:我猜测PointerCo是一个指针,但我需要在变量中存储它引用的整个矩阵。可能吗?我该怎么做?

1 个答案:

答案 0 :(得分:2)

不,你不能像这样在VBA和C ++之间“互操作”。

到目前为止,最简单的方法是在C ++端使用SAFEARRAY类型的VT_VARIANT,它映射到VBA中的经典Variant数组类型。有很多这方面的教程分散在互联网上。

如果你之前没有使用过Microsoft COM及其相关的支持类,我建议你留出一个好月份来加快速度。