http://bugs.winehq.org/show_bug.cgi?id=8758
Summary: Reversal of dimensions in SAFEARRAY marshalling Product: Wine Version: 0.9.39. Platform: PC-x86-64 OS/Version: other Status: UNCONFIRMED Severity: normal Priority: P2 Component: wine-ole AssignedTo: wine-bugs@winehq.org ReportedBy: andrew.smith@uk.standardchartered.com
I have used the functions LPSAFEARRAY_UserMarshal and LPSAFEARRAY_UserUnmarshal from the Wine API and compiled them against the MIcrosoft Windows API. I had trouble getting the windows versions of these two functions to work hence the reason for using the implementation from Wine which works well apart from a problem with multidimensional SAFEARRAY marshalling. The problem is exhibited by the dimensions of a 2D array being switched around. i.e. a [10,11] array becomes a [11,10] array.
The reason for this is that in the Windows API the SAFEARRAY::rgsabound array elements are actually in the reverse order from the SAFEARRAYBOUND array passed in as a parameter to SafeArrayCreateEx. On Windows the following code produces two SAFEARRAYs p1 and p2 that have their dimensions switched :
SAFEARRAYBOUND bounds[2]; bounds[0].lLbound =0; bounds[0].cElements =10; bounds[1].lLbound =0; bounds[1].cElements =14; SAFEARRAY* p1 = SafeArrayCreateEx(VT_UI1, 2, bounds, NULL); SAFEARRAY* p2 = SafeArrayCreateEx(VT_UI1, p1->cDims, p1->rgsabound, NULL);
It may well be that the SAFEARRAY descriptor in Wine does not mirror the Windows implementation in this way which may be a bug in itself. In any case the marshalling code in wine does not cater for this reversal.
http://source.winehq.org/source/dlls/oleaut32/usrmarshal.c#L880 http://source.winehq.org/source/dlls/oleaut32/usrmarshal.c#L1006