If you want to use IDispatch, try the following example ( use the debugger to examine the LPBYTE pointer after Invoke returns) -
SAFEARRAY *pByteArray = CreateEmptyByteArray(16);
DISPID did{ 0 };
DISPPARAMS dispparams = { nullptr, nullptr, 0, 0 };
PWSTR pszMethod = L"PassByteArray";
HRESULT hr = ptrTest->GetIDsOfNames(IID_NULL, &pszMethod, 1, LOCALE_USER_DEFAULT, &did);
if (SUCCEEDED(hr))
{
VARIANT vByteArray, vResult;
VariantInit(&vByteArray);
VariantInit(&vResult);
V_VT(&vByteArray) = VT_ARRAY | VT_BYREF | VT_UI1;
V_ARRAYREF(&vByteArray) = &pByteArray;
dispparams.rgvarg = &vByteArray;
dispparams.cArgs = 1;
hr = ptrTest->Invoke(did, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &vResult, nullptr, nullptr);
if (SUCCEEDED(hr))
{
LPBYTE pBytes = nullptr;
hr = SafeArrayAccessData(pByteArray, (LPVOID*) &pBytes);
hr = SafeArrayUnaccessData(pByteArray);
}
}
SafeArrayDestroy(pByteArray);