谁能告诉我如何从 Java 调用 Objectice-C 方法。
我听说了 JNI 和 JNA 的两种技术。
有一个用 Objective-C 编写的用于 IOS 应用程序的代码,我想在 Java 项目中使用该代码。
谁能告诉我如何从 Java 调用 Objectice-C 方法。
我听说了 JNI 和 JNA 的两种技术。
有一个用 Objective-C 编写的用于 IOS 应用程序的代码,我想在 Java 项目中使用该代码。
Rococoa有助于使用 Java 中的 ObjectiveC 代码。
JNA是一个可用于访问本机方法的库。如果您的应用程序的其余部分是用 Java 编写的,这是非常实用的,因为您可以避免编写任何本机代码。
要与 Objective-C 交互,您需要与 Objective-C 的运行时库进行交互。这是一个非常基本的例子。
// This method sets NSWindow.allowsAutomaticWindowTabbing to false.
// Note that it will terminate your application on macOS 10.11 and earlier as described below.
// https://developer.apple.com/documentation/appkit/nswindow/1646657-allowsautomaticwindowtabbing
void disableAutomaticWindowTabbing() {
Pointer classId = FoundationLibrary.INSTANCE.objc_getClass("NSWindow");
Pointer selector = FoundationLibrary.INSTANCE.sel_registerName("setAllowsAutomaticWindowTabbing:");
FoundationLibrary.INSTANCE.objc_msgSend(classId, selector, false);
}
// The interface of the runtime library of Objective-C.
interface FoundationLibrary extends Library {
FoundationLibrary INSTANCE = Native.load(
"Foundation",
FoundationLibrary.class,
Map.of(Library.OPTION_STRING_ENCODING, StandardCharsets.UTF_8.name()));
// https://developer.apple.com/documentation/objectivec/1418952-objc_getclass?language=objc
Pointer objc_getClass(String className);
// https://developer.apple.com/documentation/objectivec/1418557-sel_registername?language=objc
Pointer sel_registerName(String selectorName);
// https://developer.apple.com/documentation/objectivec/1456712-objc_msgsend?language=objc
// The return type is actually "generic". You might need to declare this function
// multiple times with different return types if you need them.
void objc_msgSend(Pointer receiver, Pointer selector, Object... args);
}
但是请注意,JNA 无法处理本机异常。如果objc_msgSend
抛出异常,您的应用程序会立即崩溃。上面的示例将引发异常并因此在 macOS 10.11 及更早版本上使应用程序崩溃,因为setAllowsAutomaticWindowTabbing
在 macOS 10.12 之前不可用。
使用JNI,您需要编写自己的本地代码(即使用Objecttive-C++)。因此,您的项目设置变得更加复杂。但是,如果您希望在 Objective-C 中编写逻辑的主要部分,这可能是一个不错的选择。另请注意,Objective-C 编译器可能会发现 API 的一些误用,这会使应用程序更加健壮。我与 JNA 相比,您还能够处理本机异常。
还有JEP 389: Foreign Linker API (Incubator)。我认为它是 JNA 的替代方案,但有 JVM 的本机支持。除此之外,还有其他库和工具在 JNA 或 JNI 之上工作,专门与 Objective-C 进行交互。
Java-Objective-C-Bridge的作者的博客文章从 Java 讲 Cocoa也可能是一本有趣的读物。
我认为这是不可能的。
您可以做的是使用您想要共享的代码编写 ac/c++-library,并在 Objective-c 和 java(通过 JNI)中使用它。无论如何,您必须重写您的代码以将其移植到 java(您将有多余的源代码),或者从您的 Objective-C 项目中删除您的代码并创建您可以在您的 Objective-C 中使用的 ac 库和你的java项目。