问题
I'm using a proprietary library on linux that uses SAFEARRAY
type in a callback function:
HRESULT Write(SAFEARRAY *Data)
SAFEARRAY
is defined in a header file as typedef void SAFEARRAY
.
I must define a callback function that will get the data (eg. as *unsigned char
) and it's length (eg. as int
or size_t
) and write the data somewhere.
Something like:
HRESULT MyWrite(SAFEARRAY *Data) {
unsigned char *data = SafeArrayGetData(Data);
size_t length = SafeArrayGetLength(Data);
write_data_somewhere(data, length);
}
And then use it with the library:
ProprietaryLib::ExportThing(thing, MyWrite);
So my question is: How to get the data and it's length on linux, where I have no oaidl.h or oleauto.h header file.
回答1:
Two thoughts on the matter:
Maybe you've seen it already, but Wine implements
SAFEARRAY
. Thus you may have a look at- https://github.com/wine-mirror/wine/blob/master/dlls/oleaut32/safearray.c
- https://github.com/wine-mirror/wine/blob/master/include/oaidl.idl
- https://github.com/wine-mirror/wine/blob/master/include/oleauto.h
It seems to me that to get length and data of the array, it should be fine to just access the members of the struct. For instance, in
safearray.c
they simply readcbElements
at various places, and the methodSafeArrayAccessData
basically only returnspvData
. (In addition, it "locks" the array. The "locking" seems to be a reference counter that is checked when a SAFEARRAY is resized or freed.)One idea why your
MYSAFEARRAY
(mentioned in comments) does not work is that struct packing might interfere. In https://docs.microsoft.com/en-us/cpp/build/reference/zp-struct-member-alignment they say that Windows SDK presupposes that structs are packed on 8-byte boundaries. So perhaps you could output the raw bytes and see if you detect a pattern. If that turns out to be the problem, try to change your compiler settings.
来源:https://stackoverflow.com/questions/54345277/safearray-on-linux