【发布时间】:2021-08-30 09:20:48
【问题描述】:
我有一个包含此函数声明的COM interface
HRESULT _stdcall mgAPI::IMGGeocoding::GetCoordinates([in] BSTR Postcode,
[in] BSTR Location,
[in] BSTR Street,
[in] VARIANT_BOOL SearchFuzzy,
[out] VARIANT * Values)
Parameters
[in] Postcode Postal code (with or without leading country code), e.g. "D76131"
[in] Location Town name, e.g. "Karlsruhe"
[in] Street Street and house number, e.g. "Stumpfstr. 1"
[in] SearchFuzzy if set to true, the search will be more "tolerant" and will normally give more results.
[out] Values 2-dimensional variant array (0-based in both dimensions).
The size of the first dimension is equal to the number of returned search results.
The size of the second dimension is 7.
使用这个example我在JNA中映射了如下函数:
public String[] getCoordinates(String inPostcode, String inLocation, String inStreet, boolean inSearchFuzzy) {
String[] retVal = null;
SAFEARRAY safeArray = SAFEARRAY.createSafeArray(new WTypes.VARTYPE(Variant.VT_VARIANT), 7);
try {
BSTR postcode = OleAuto.INSTANCE.SysAllocString(inPostcode);
BSTR location = OleAuto.INSTANCE.SysAllocString(inLocation);
BSTR street = OleAuto.INSTANCE.SysAllocString(inStreet);
VARIANT_BOOL searchFuzzy = new VARIANT_BOOL(inSearchFuzzy);
PointerByReference pbr = new PointerByReference(safeArray.getPointer());
VARIANT values = new VARIANT();
values.setValue(new VARTYPE(Variant.VT_BYREF), new PVOID(pbr.getPointer()));
values.setVarType((short) (Variant.VT_BYREF | Variant.VT_ARRAY | Variant.VT_VARIANT));
HRESULT hres = (HRESULT)this._invokeNativeObject(7, new Object[]{this.getPointer(), postcode, location, street, searchFuzzy, values}, HRESULT.class);
if (COMUtils.SUCCEEDED(hres)) {
if (!pbr.getValue().equals(safeArray.getPointer())) {
safeArray.destroy();
safeArray = new SAFEARRAY(pbr.getValue());
}
safeArray.read();
Pointer pointer = safeArray.accessData();
try {
retVal = pointer.getStringArray(0, safeArray.getUBound(0) - safeArray.getLBound(0) + 1);
} finally {
safeArray.unaccessData();
}
}
} catch(Exception e) {
e.printStackTrace();
} finally {
if (safeArray != null) {
safeArray.destroy();
}
}
return retVal;
}
Array 中的值始终为null。
将 VARIANT* 传递到接口并获取二维变量数组的正确方法是什么?
【问题讨论】:
-
不了解 java/jna,但是,从您的函数原型中,您只需分配一个空的 VARIANT 结构,并在 调用函数(构建数组不是您的责任)所以这意味着您要首先检查它的类型(它应该是 VT_ARRAY | 类似 VT_ARRAY | VT_VARIANT 或 VT_ARRAY | VT_I4 等)并使用数组成员。读取所有内容后,您应该释放返回的 VARIANT 可能持有的内存。 (使用原生 C++/SDK 它是 VariantClear)