I have in a DLL the following code, which is supposed to take some input from a routine written in VBA, do some stuff with it, and return two 2D-arrays back (so a function is not really doable, besides, if I wanted to return an array containing the other two, I'd have to face code-optimization problems in VBA), which can be accessed from VBA. Without further ado, the code looks like this:
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 */
}
Which I call from VBA as follows:
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
is because the input arrays RealCo
, RealCr
, ImagCo
, ImagCr
are actually Single
type in VBA.
It works, but my problem is the following: as I move from the last }
in C++ to VBA, the content of CoPol
and CrPol
(which are the two matrices I would like to use further in the VBA code) disappears.
Notice that I can actually debug the code and check that CoPol
and CrPol
do contain data. I tried to pass them to another subroutine in C++, and since it didn't work as well, I came out with the solution of passing them via reference:
void _stdcall MySub(VARIANT RealCo, VARIANT ImagCo, VARIANT RealCr, VARIANT ImagCr, ULONG PointsTheta, ULONG PointsPhi, double Res, VARIANT &CoPol, VARIANT &CrPol)
This solved my problem inside C++ but not between C++ and VBA. I also tried giving back pointers to the VARIANTS, and calling the needed arrays ByRef
and As Long
, but it doesn't work (CoPol
and CrPol
are then in VBA just a Long
number, which I can't work with).
What should I write in order to make VBA able to access the values inside the matrix built in C++?
EDIT: if you want to downvote, at least explain why.
How do you free memory afterwards if its allocated by a single function call in C++?
I would have done it the other way; declared and dim'ed the arrays in VBA and then passed pointer to array data to your C++ function, which then fills it up with values.
(Btw, I think its __stdcall with two underscores.)
void __stdcall fillarray(const int n, double *out) {
for (int i = 0; i < n; ++i) {
out[i] = i;
}
}
And then
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