我试图在Apple的Security.h
框架中调用一个方法,该方法通过引用返回结构,如下所示:
int findSomething(SomeStruct *s)
(具体来说,它是this method,我试图获得itemRef
。还有一个使用示例here。)问题是我不知道SomeStruct
有哪些字段或有多大字段。它只存在于传递给其他本机库函数。所以,我想要这样的东西(Java):
interface SomeLib extends Library {
int findSomething(Pointer p);
}
...
Pointer p = ... // Not sure how to make this
nativeLib.findSomething(p)
// Do something with p
如果我可以用Java做sizeof(SomeStruct)
,我想我可以使用JNA Memory
来创建指针。我可以编写一个返回sizeof(SomeStruct)
的本机方法,但我不想在我自己的代码中添加本机组件。
这与this question类似,但是它询问了SomeStruct
字段在运行时是否已知的情况,而在我的情况下,字段被图书馆作者故意隐藏。< / p>
答案 0 :(得分:2)
SecKeychainItemRef
类型is defined to be a pointer to the struct。这意味着SecKeychainFindGenericPassword
函数实际上需要一个指向的指针作为itemRef
参数,因此,您可以使用JNA PointerByReference
类作为参数。
成功通话后,您可以使用PointerByReference.getValue()
获取不透明指针。
/* int SecKeychainFindGenericPassword(
* Pointer keychainOrArray,
* int serviceNameLength,
* String serviceName,
* int accountNameLength,
* String accountName,
* IntByReference *passwordLength,
* PointerByReference passwordData,
* PointerByReference itemRef
* );
*/
static void main() {
IntByReference passLength = new IntByReference(0);
PointerByReference passwordData = new PointerByReference();
PointerByReference itemRef = new PointerByReference();
int result = SecKeychainFindGenericPassword(
keychainOrArray,
"service name".length(),
"service name",
"account".length(),
"account",
passLength,
passwordData,
itemRef
);
if (result == 0) {
System.out.printf(
"OSStatus: %d, passDataPtr: 0x%08X, itemRefPtr: 0x%08X%n",
result,
Pointer.nativeValue(passwordData.getValue()),
Pointer.nativeValue(itemRef.getValue())
);
} else {
/* Use SecCopyErrorMessageString to get a human-readable message */
System.out.printf("An error occurred: %d%n", result);
}
}
如果您在实际项目中调用此方法,我建议您创建一个名为SecKeychainItemRef
的类,该类扩展PointerByReference
类。这会以更清晰的方式将参数的类型传递给读者,即使它不允许您访问结构的内部。