谁能告诉我如何从 Java 调用 Objectice-C 方法。
我听说过 JNI 和 JNA 两种技术。
有一段用 Objective-C 编写的 IOS 应用程序代码,我想在 Java 项目中使用该代码。
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
抛出异常,您的应用程序会立即崩溃。由于 setAllowsAutomaticWindowTabbing
在 macOS 10.12 之前不可用,因此上面的示例将引发异常并使应用程序在 macOS 10.11 及更早版本上崩溃。
使用JNI,您需要编写自己的本机代码(即使用Objecttive-C++)。因此,您的项目设置变得更加复杂。然而,如果您希望用 Objective-C 编写逻辑的主要部分,那么它可能是一个不错的选择。另请注意,Objective-C 编译器可能会捕获 API 的一些误用,从而使应用程序更加健壮。与 JNA 相比,您还可以处理本机异常。
还有JEP 389:外部链接器 API(孵化器)。我认为它是 JNA 的替代方案,但具有 JVM 的本机支持。除此之外,还有其他库和工具在 JNA 或 JNI 之上工作,专门与 Objective-C 交互。
来自 Java-Objective-C-Bridge 作者的博客文章 Speaking Cocoa From Java 也可能是一本有趣的读物。
Rococoa 方便使用 Java 中的 ObjectiveC 代码。
我认为这是不可能的。
您可以做的是使用您想要共享的代码编写一个 c/c++ 库,并在 Objective-C 和 Java 中使用它(通过 JNI)。 不管怎样,你必须重写你的代码,要么将它移植到java(在那里你会有多余的源代码),要么从你的objective-c项目中删除你的代码并创建一个可以在你的objective-c中使用的c库和你的 java 项目。