在JNA中获取参数返回的不透明结构 [英] Getting an opaque struct returned by parameter in JNA
问题描述
我正在尝试在Apple的Security.h
框架中调用通过引用返回结构的方法,如下所示:
I'm trying to call a method in Apple's Security.h
framework that returns a struct by reference, like so:
int findSomething(SomeStruct *s)
(具体来说,它是此方法,我我正在尝试获取itemRef
.有一个用法示例
(Specifically, it's this method, and I'm trying to get itemRef
. There's a usage example here.) The problem is that I don't know what fields SomeStruct
has or how big it is. It only exists to be passed to other native library functions. So, I want something like this (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)
,则可以使用JNAs Memory
创建指针.我可以编写一个本机方法来返回sizeof(SomeStruct)
,但是我不想在自己的代码中添加本机组件.
If I could do sizeof(SomeStruct)
in Java, I could create the pointer using JNAs Memory
, I think. I could write a native method to return sizeof(SomeStruct)
, but I don't want to add a native component to my own code.
这类似于此问题,但它询问了SomeStruct
的字段在运行时是已知的,而就我而言,这些字段被库作者有意遮盖了.
This is similar to this question, but it asks about a case where the fields of SomeStruct
are known at runtime, whereas, in my case, the fields are obscured intentionally by the library authors.
推荐答案
The SecKeychainItemRef
type is defined to be a pointer to the struct. This means that the SecKeychainFindGenericPassword
function actually expects a pointer to a pointer as the itemRef
argument, and as such, you can use the JNA PointerByReference
class as the argument.
成功拨打电话后,您可以使用 PointerByReference.getValue()
以获得不透明的指针.
After a successful call, you can use PointerByReference.getValue()
to get the opaque pointer.
/* 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
类.即使无法让您访问结构的内部结构,也可以以更清晰的方式将参数的类型传达给阅读器.
If you're calling this method in an actual project, I would suggest creating a class named SecKeychainItemRef
which extends the PointerByReference
class. This communicates the argument's type to the reader in a clearer fashion, even if it doesn't let you access the internals of the struct.
这篇关于在JNA中获取参数返回的不透明结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!