Reputation: 9546
I have a C++ DLL; I am trying to call an exported function in VBA that will return an array. To avoid having to deal with SAFEARRAY as a return type, I've chosen to pass an array into the function by reference and have the function modify this array's values. But the VBA implementation doesn't return the modified values, even though I'm using ByRef
to pass in the array.
Header:
namespace myProject
{
class FileOperator
{
public:
static __declspec(dllexport) void __stdcall testArray(long* docArray);
};
}
Implementation:
#include "stdafx.h"
#include "myProject.h"
using namespace std;
namespace myProject
{
void __stdcall FileOperator::testArray(long* docArray)
{
docArray[0]=303;
docArray[1]=909;
}
}
Console app test:
#include "stdafx.h"
#include <iostream>
#include "../myProject/myProject.h"
using namespace std;
int main()
{
long docArray[2]={0};
myProject::FileOperator::testArray(docArray);
cout << docArray[0] << "\n" << docArray[1];
}
VBA test:
Private Declare Sub testArray Lib "C:\pathToDLL\myProject.dll" _
Alias "?testArray@FileOperator@myProject@@SGXPAJ@Z" _
(ByRef docArray() As Long)
Public Sub test()
Dim docArray(1) As Long
docArray(0) = 0
docArray(1) = 0
testArray docArray
For Each x In docArray
Debug.Print x
Next
End Sub
The C++ console app outputs:
303
909
The VBA app outputs:
0
0
Why aren't the array changes being saved once the testArray()
function exits? Shouldn't the ByRef
keyword make this possible?
Upvotes: 1
Views: 6005
Reputation: 78155
ByRef docArray()
makes the expected sense when calling inside VB(A) - it allows you to replace the array stored in the variable with another array (as well as change the elements of the passed array without replacing the whole array).
For declared functions, use ByRef docArray As Long
, and then pass docArray(LBound(docArray))
as the argument (the pointer to the first element).
Upvotes: 3