1

I need an array as an output parameter in a C++ function which is then called from VB6. I am using VS 2015 with C++ for the DLL project.

I couldn't find a way to create the array and return it in the C++ code (which would be the best solution), so I am trying to create a big enough array in the VB6 code and pass it as a parameter, then change it in the C++ code and use the result values in VB6 again. Below is an example with a byte array but my final function needs to be an array of structures, so solutions with string at the place of the byte array don't work.

C++ code (the call itself works):

__declspec(dllexport) void  __stdcall Test(
    char* data, int* len)
{
    *len = 3;
    data[0] = 1;
    data[1] = 2;
    data[2] = 3;
}

VB6 code: the code works, the length parameter is changed as expected but the data array does not change, it remains zeros:

Private Declare Sub Test Lib "MyDll.dll" (ByRef data() As Byte, length As Long)

Dim data(10) As Byte
Dim length As Long
Call Test(data, length)
GSerg
  • 76,472
  • 17
  • 159
  • 346
Vladimir
  • 1,425
  • 16
  • 31
  • Possible duplicate of [How to create an array of strings in VBA/Excel and send it to a C++ DLL so that it can be itterated through in the DLL](https://stackoverflow.com/q/44637879/11683) – GSerg Oct 05 '17 at 18:58
  • It explains all the `SAFEARRAY*` business that you would need to "create the array and return it in the C++ code (which would be the best solution)". Parameter types stay the same, the only difference is that you'd also be calling `SafeArrayCreate` on the C++ side. – GSerg Oct 05 '17 at 19:07

1 Answers1

0

I found a working solution here.

It is to declare and call the function in VB6 like this:

Private Declare Sub Test Lib "MyDll.dll" (ByRef data As Byte, length As Long)

Dim data(10) As Byte
Dim length As Long
Call Test(data(LBound(data)), length)
Vladimir
  • 1,425
  • 16
  • 31
  • 1
    Actually I did not mention this technique because it is generally not suited for arrays of user-defined types. It is okay for arrays of built-in types, and it may be okay for structures that do not contain strings, but for structures with strings it is not going to be okay because, seeing the `byref data as struct_type`, VB will convert just the first instance of the structure [to ANSI](https://stackoverflow.com/a/23980044/11683) and pass a pointer to that, which will break the C++ code that will try to use pointer math on that pointer. – GSerg Oct 06 '17 at 11:44
  • 1
    To be safe, you need to declare `byval data as long`, pass `VarPtr(data(LBound(data))`, and handle wide strings on the C++ side. – GSerg Oct 06 '17 at 11:44