我试图重写一段包含从VBA到VB.NET的C ++ dll调用的代码。
特别是有一个C ++函数,我在dll中调用,对float
的几个二维数组执行某些操作:
int __stdcall FindPolarization(int PointsTheta, int PointsPhi, float* Real1, float* Imag1 = nullptr)
{
double Max[4] = { -999, -999, -999, -999 }; // Max values
long MaxPos[4][2] = { -999, -999, // Max Theta and Max Phi
-999, -999,
-999, -999,
-999, -999 };
float* Pointers[4][2];
double DeltaTheta = static_cast<double>(180.0 / PointsTheta);
double DeltaPhi = static_cast<double>(360.0 / PointsPhi);
vector<vector<vector<double>>> Ampl;
// Setup
Pointers[0][0] = Real1;
Pointers[0][1] = Imag1;
Pointers[1][0] = Real2;
Pointers[1][1] = Imag2;
Pointers[2][0] = Real3;
Pointers[2][1] = Imag3;
Pointers[3][0] = Real4;
Pointers[3][1] = Imag4;
if (Real3 != nullptr && Real4 != nullptr && Imag3 != nullptr && Imag4 != nullptr)
{
Ampl.resize(4, vector<vector<double>>(PointsTheta + 1, vector<double>(PointsPhi, 0)));
Real3 = nullptr; Imag3 = nullptr; Real4 = nullptr; Imag4 = nullptr;
}
else
{
Ampl.resize(2, vector<vector<double>>(PointsTheta + 1, vector<double>(PointsPhi, 0)));
}
Real1 = nullptr; Imag1 = nullptr; Real2 = nullptr; Imag2 = nullptr;
// Coordinates transformation + Maximum storage
Concurrency::parallel_for(0, PointsPhi, [&](int j)
{
double PhiRad = j * DeltaPhi * Deg2Rad;
double CosPhi = cos(PhiRad);
double SinPhi = sin(PhiRad);
int ind;
pair<double, double> AmplCoCr;
for (int i = 0; i <= PointsTheta; i++)
{
ind = j * (PointsTheta + 1) + i;
for (int k = 0; k < static_cast<int>(Ampl.size()); k = k + 2)
{
AmplCoCr = AmplCalc(ind, Pointers[k][0], Pointers[k][1], Pointers[k + 1][0], Pointers[k + 1][1], CosPhi, SinPhi);
Ampl[k][i][j] = AmplCoCr.first;
Ampl[k + 1][i][j] = AmplCoCr.second;
if (Ampl[k][i][j] > Max[k])
{
Max[k] = Ampl[k][i][j];
MaxPos[k][0] = i;
MaxPos[k][1] = j;
}
if (Ampl[k + 1][i][j] > Max[k + 1])
{
Max[k + 1] = Ampl[k + 1][i][j];
MaxPos[k + 1][0] = i;
MaxPos[k + 1][1] = j;
}
}
}
});
double A = max(max(Max[0], Max[1]), max(Max[2], Max[3]));
if (A > Max[1] && A > Max[2] && A > Max[3]) return 45;
else if (A > Max[0] && A > Max[2] && A > Max[3]) return 135;
else if (A > Max[0] && A > Max[1] && A > Max[3]) return 90;
return 0; // else if (A > Max[0] && A > Max[1] && A > Max[2])
}
pair<double, double> AmplCalc(int index, float* RealCo, float* ImagCo, float* RealCr, float* ImagCr, double CosPhi, double SinPhi)
{
double A, B;
const double RealCoij = static_cast<double>(RealCo[index]);
const double RealCrij = static_cast<double>(RealCr[index]);
const double ImagCoij = static_cast<double>(ImagCo[index]);
const double ImagCrij = static_cast<double>(ImagCr[index]);
A = RealCoij * CosPhi + RealCrij * SinPhi;
B = ImagCoij * CosPhi + ImagCrij * SinPhi;
double Co = 10 * log10(A * A + B * B);
A = (RealCoij * SinPhi * (-1) + RealCrij * CosPhi);
B = (ImagCoij * SinPhi * (-1) + ImagCrij * CosPhi);
double Cr = 10 * log10(A * A + B * B);
return make_pair(Co, Cr);
}
在VBA环境中导入的内容为:
Private Declare Function FindPolarization Lib "EvalFunc.dll" (ByVal PointsTheta As Long, ByVal PointsPhi As Long, ByRef RealLev1 As Single, ByRef ImagLev1 As Single = 0) As Long
并通过以下代码调用:
Dim RealLev1() As Single, ImagLev1() As Single
Dim PolMax As Long, FFThetaPoints As Long, FFPhiPoints As Long
' Arrays are filled here through a function that determines their dimensions and values
FFThetaPoints = UBound(RealLev1, 1)
FFPhiPoints = UBound(RealLev1, 2)
PolMax = FindPolarization(FFThetaPoints, FFPhiPoints, RealLev1(0, 0), ImagLev1(0, 0))
这适用于VBA,但我一直试图将其转换为VB.NET并且失败了。
如果我无法更改dll中的C ++代码,我已停止使用以下代码。
该函数的导入如下:
<DllImport("myDll.dll", SetLastError:=True, CharSet:=CharSet.Unicode, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function FindPolarization(ByVal PointsTheta As Integer, ByVal PointsPhi As Integer, ByRef RealLev1 As Single, _
Optional ByRef ImagLev1 As Single = Nothing) As Integer
End Function
调用它的代码是:
Dim FFThetaPoints As Integer, FFPhiPoints As Integer, PolMax As Integer
Dim RealLev1(,) As Single = Array.CreateInstance(GetType(Single), 1, 1)
Dim ImagLev1(,) As Single = Array.CreateInstance(GetType(Single), 1, 1)
FFThetaPoints = UBound(RealLev1, 1)
FFPhiPoints = UBound(RealLev1, 2)
PolMax = ImportDll.FindPolarization(FFThetaPoints, FFPhiPoints, RealLev1(0, 0), ImagLev1(0, 0))
现在,这些数组是System.Array
类型,因为需要它们的特定功能。
虽然在VBA中我得到了一些结果,但在VB.NET中我获得了其他结果。我认为这与我如何声明Single
数组有关,但我不确定。
我做错了什么?
答案 0 :(得分:0)
我必须在这里给予@Craig所有的功劳。
VBA和VB.NET确实有不同的矩阵寻址逻辑(列主要与行主要),因此我不得不转换所有2D数组,而无需交换FFThetaPoints
和FFPhiPoints
。
值得一提的是,我尝试使用Excel.Application
Worksheetfunction.Transpose
方法,该方法无效。所以我必须编写自己的代码来转置矩阵。