我在DLL中有以下代码,它应该从用VBA编写的例程中获取一些输入,用它做一些事情,然后返回两个2D数组(这样一个函数)并不是真的可行,此外,如果我想返回一个包含其他两个的数组,我必须面对VBA中的代码优化问题),可以从VBA访问。 不用多说,代码看起来像这样:
void _stdcall MySub(VARIANT RealCo, VARIANT ImagCo, VARIANT RealCr, VARIANT ImagCr, ULONG PointsTheta, ULONG PointsPhi, double Res, VARIANT CoPol, VARIANT CrPol)
{
/* Do my stuff here, and at the end produces the following arrays */
CoPol.vt = VT_ARRAY | VT_VARIANT;
CrPol.vt = VT_ARRAY | VT_VARIANT;
sab2[1].lLbound = 0; sab2[1].cElements = 360;
sab2[0].lLbound = 0; sab2[0].cElements = 360;
CoPol.parray = SafeArrayCreate(VT_VARIANT, 2, sab2);
CrPol.parray = SafeArrayCreate(VT_VARIANT, 2, sab2);
/* Those arrays are then stuffed with data */
}
我从VBA打电话如下:
Private Declare Sub MySub Lib "Mypath/MyFile.dll" ( _
ByVal RealCo As Variant, _
ByVal ImagCo As Variant, _
ByVal RealCr As Variant, _
ByVal ImagCr As Variant, _
ByVal PointsTheta As Long, _
ByVal PointsPhi As Long, _
ByVal Res As Double, _
ByVal CoPol As Variant, _
ByVal CrPol As Variant)
Dim CoPol As Variant, CrPol As Variant
' [...]
MySub CVar(RealCo), CVar(ImagCo), CVar(RealCr), CVar(ImagCr), PointsTheta, PointsPhi, Resolution, CoPol, CrPol
CVar
是因为输入数组RealCo
,RealCr
,ImagCo
,ImagCr
实际上是VBA中的Single
类型。
它有效,但我的问题如下:当我从C ++中的最后一个}
移动到VBA时,CoPol
和CrPol
的内容(这是我的两个矩阵)想在VBA代码中进一步使用)消失。
请注意,我实际上可以调试代码并检查CoPol
和CrPol
是否包含数据。我试图将它们传递给C ++中的另一个子程序,因为它也不起作用,我提出了通过引用传递它们的解决方案:
void _stdcall MySub(VARIANT RealCo, VARIANT ImagCo, VARIANT RealCr, VARIANT ImagCr, ULONG PointsTheta, ULONG PointsPhi, double Res, VARIANT &CoPol, VARIANT &CrPol)
这解决了我在C ++ 中的问题,但在C ++和VBA之间没有解决。我也尝试过返回指向VARIANTS的指针,并调用所需的数组ByRef
和As Long
,但它不起作用(CoPol
和CrPol
然后VBA只是一个Long
号码,我无法使用。)
为了使VBA能够访问C ++内置矩阵内的值,我应该写什么?
编辑:如果你想进行投票,至少解释原因。
答案 0 :(得分:1)
如果用C ++中的单个函数调用分配内存,你如何释放内存?
我会以另一种方式做到这一点;在VBA中声明并调暗数组,然后将指向数组数据的指针传递给C ++函数,然后用函数填充它。
(顺便说一句,我认为它的__stdcall有两个下划线。)
void __stdcall fillarray(const int n, double *out) {
for (int i = 0; i < n; ++i) {
out[i] = i;
}
}
然后
Public Declare PtrSafe Sub fillarray Lib "Mypath/MyFile.dll" (ByVal n As Long, ByRef out As Double)
Dim A() as Double
Redim A(1 to 100)
fillarray 100, A(1) 'A(1) first element pointing to data