获取由 JNA 中的参数返回的不透明结构
Getting an opaque struct returned by parameter in JNA
我正在尝试调用 Apple 的 Security.h
框架中的一个方法,该方法 return 是一个引用结构,如下所示:
int findSomething(SomeStruct *s)
(具体是this method, and I'm trying to get itemRef
. There's a usage example 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
创建指针。我可以为 return sizeof(SomeStruct)
编写本地方法,但我不想将本地组件添加到我自己的代码中。
这类似于 this question,但它询问的是 SomeStruct
的字段在运行时已知的情况,而在我的例子中,这些字段被库作者故意遮盖了.
SecKeychainItemRef
类型is defined to be a pointer to the struct。这意味着 SecKeychainFindGenericPassword
函数实际上需要一个指向指针 的 指针作为 itemRef
参数,因此,您可以使用 JNA PointerByReference
class 作为参数。
调用成功后,可以使用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
的 class,它扩展了 PointerByReference
class。这以更清晰的方式将参数的类型传达给 reader,即使它不允许您访问结构的内部。
我正在尝试调用 Apple 的 Security.h
框架中的一个方法,该方法 return 是一个引用结构,如下所示:
int findSomething(SomeStruct *s)
(具体是this method, and I'm trying to get itemRef
. There's a usage example 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
创建指针。我可以为 return sizeof(SomeStruct)
编写本地方法,但我不想将本地组件添加到我自己的代码中。
这类似于 this question,但它询问的是 SomeStruct
的字段在运行时已知的情况,而在我的例子中,这些字段被库作者故意遮盖了.
SecKeychainItemRef
类型is defined to be a pointer to the struct。这意味着 SecKeychainFindGenericPassword
函数实际上需要一个指向指针 的 指针作为 itemRef
参数,因此,您可以使用 JNA PointerByReference
class 作为参数。
调用成功后,可以使用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
的 class,它扩展了 PointerByReference
class。这以更清晰的方式将参数的类型传达给 reader,即使它不允许您访问结构的内部。