Objective-C 中缺少 JNI header
JNI header missing in Objective-C
我的项目中有一个 file.c
,其中有 #include <jni.h>
header 文件。将此 header 文件包含在项目或 macOS 中的过程是什么?
假设您有以下代码
#include "jni.h"
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
options[0].optionString = "-Djava.class.path=_HERE_GOES_LOCATION_OF_JNICOOKBOK_/jnicookbook/recipeNo051/target";
vm_args.options = options;
vm_args.ignoreUnrecognized = 0;
vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 1;
int status = JNI_CreateJavaVM (&jvm, (void **) &env, &vm_args);
if (status < 0 || !env) {
printf ("Error - JVM creation failed\n");
return 1;
}
jclass cls_Main = (*env)->FindClass (env, "recipeNo051/Main");
jmethodID method_displayMessage = (*env)->GetStaticMethodID (env, cls_Main, "displayMessage", "()V");
(*env)->CallStaticVoidMethod(env, cls_Main, method_displayMessage);
(*jvm)->DestroyJavaVM( jvm );
}
return 0;
}
为了运行你需要
libjvm.dylib
的位置
- headers
的位置
- 从
main.m
调用的已编译 Java classes 的位置
让我们从库和 headers 开始。您必须确保在以下路径中搜索包含(请注意,我使用的是 jdk-11.0.4):
/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home/include
/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home/include/darwin/
您必须确保将以下路径添加到 Library Search Path
和 Runpath Search Paths
/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home/lib/server
你应该有这样的设置:
确保将您的代码链接到 libjvm.dylib
。将其添加到 Build Phases
中
您可以通过选择 Add Other...
来指定它的位置
运行你的代码,但是!确保在调用方法 JNI_CreateJavaVM
之前忽略 SIGSEGV
。你可以在 lldb
console
中忽略它
(lldb) process handle --pass true --stop false SIGSEGV
继续后,您可以看到您的 JVM
实例从 recipeNo051
.
调用 classes
class 的源代码:recipeNo051/Main
可在此处找到:https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo051
更新
我的项目中有一个 file.c
,其中有 #include <jni.h>
header 文件。将此 header 文件包含在项目或 macOS 中的过程是什么?
假设您有以下代码
#include "jni.h"
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
JNIEnv *env;
JavaVM *jvm;
JavaVMInitArgs vm_args;
JavaVMOption options[3];
options[0].optionString = "-Djava.class.path=_HERE_GOES_LOCATION_OF_JNICOOKBOK_/jnicookbook/recipeNo051/target";
vm_args.options = options;
vm_args.ignoreUnrecognized = 0;
vm_args.version = JNI_VERSION_1_8;
vm_args.nOptions = 1;
int status = JNI_CreateJavaVM (&jvm, (void **) &env, &vm_args);
if (status < 0 || !env) {
printf ("Error - JVM creation failed\n");
return 1;
}
jclass cls_Main = (*env)->FindClass (env, "recipeNo051/Main");
jmethodID method_displayMessage = (*env)->GetStaticMethodID (env, cls_Main, "displayMessage", "()V");
(*env)->CallStaticVoidMethod(env, cls_Main, method_displayMessage);
(*jvm)->DestroyJavaVM( jvm );
}
return 0;
}
为了运行你需要
libjvm.dylib
的位置
- headers 的位置
- 从
main.m
调用的已编译 Java classes 的位置
让我们从库和 headers 开始。您必须确保在以下路径中搜索包含(请注意,我使用的是 jdk-11.0.4):
/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home/include
/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home/include/darwin/
您必须确保将以下路径添加到 Library Search Path
和 Runpath Search Paths
/Library/Java/JavaVirtualMachines/jdk-11.0.4.jdk/Contents/Home/lib/server
你应该有这样的设置:
确保将您的代码链接到 libjvm.dylib
。将其添加到 Build Phases
您可以通过选择 Add Other...
运行你的代码,但是!确保在调用方法 JNI_CreateJavaVM
之前忽略 SIGSEGV
。你可以在 lldb
console
(lldb) process handle --pass true --stop false SIGSEGV
继续后,您可以看到您的 JVM
实例从 recipeNo051
.
class 的源代码:recipeNo051/Main
可在此处找到:https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo051
更新