Mic*_*son 6 c++ java java-native-interface
我正在将Java嵌入到C++应用程序中.作为其中的一部分,我需要向Java公开本机函数,以及从C++调用java函数.
我是否需要将我想要调用的函数放入共享库中?或者它们可以以某种方式编译到主机应用程序中?
这是我到目前为止所尝试的内容,但它提供了一个java.lang.UnsatisfiedLinkError
汇编
我正在使用OS X 10.5构建
g++ -Wall -I/System/Library/Frameworks/JavaVM.framework/Headers/ -framework JavaVM -g test.cpp
Run Code Online (Sandbox Code Playgroud)
Java测试文件:TestObject.java
// To build this you need to do a `javac TestObject.java`
// To get the signatures do a `javap -d TestObject`
// To generate the .h file do a `javah TestObject`
public class TestObject
{
public native TestObject get_property( String k );
}
Run Code Online (Sandbox Code Playgroud)
C++测试文件:test.cpp
#include <jni.h>
#include <assert.h>
JNIEXPORT jobject JNICALL Java_TestObject_get_1property(JNIEnv * jni_env, jobject obj, jstring key)
{
//Just a stub implementation for now.
jclass klass = jni_env->GetObjectClass( obj );
jmethodID constructor = jni_env->GetMethodID( klass, "<init>", "()V");
jobject retval = jni_env->NewObject(klass, constructor );
return retval;
}
int main()
{
JavaVM* jvm;
JavaVMInitArgs vm_args;
JavaVMOption options[1];
vm_args.version = JNI_VERSION_1_4;
vm_args.nOptions = 1;
options[0].optionString = "-Djava.class.path=.";
vm_args.options = options;
vm_args.ignoreUnrecognized = JNI_FALSE;
JNIEnv * env;
JNI_CreateJavaVM(&jvm, (void **)&env, &vm_args);
jclass klass = (env)->FindClass("TestObject");
assert( klass );
jmethodID constructor = env->GetMethodID( klass, "<init>", "()V");
assert( constructor );
jobject obj = env->NewObject(klass, constructor );
jmethodID test_method = (env)->GetMethodID( klass, "get_property", "(Ljava/lang/String;)LTestObject;" );
assert( test_method );
jvalue args[1];
args[0].l = env->NewStringUTF("k");
jobject rv = env->CallObjectMethodA(obj, test_method, args );
jthrowable exc = env->ExceptionOccurred();
if(exc)
{
env->ExceptionDescribe();
env->ExceptionClear();
}
//TODO: do something with rv
Run Code Online (Sandbox Code Playgroud)
}
通常,JVM期望在通过System#load或者加载的共享库中查找本机方法定义System#loadLibrary,并且在大多数情况下这是最方便的方法.但是,对于像您这样的情况,确实存在一种替代方案,您希望将实现直接包含在可执行文件中.
如果调用JNIEnv::RegisterNatives,则可以向JVM传递与特定类中的本机方法相对应的函数指针列表.当某些Java代码调用其中一个方法时,JVM将知道调用您传递给的函数指针RegisterNatives而不是搜索动态加载的库.
JNINativeMethod methods[] = {
{
"frobFabulously",
"(Ljava/lang/Object;)V",
reinterpret_cast<void*>(NativeFrobFabulouslyImpl)
},
};
env->RegisterNatives(clazz, methods, sizeof(methods)/sizeof(JNINativeMethod));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
680 次 |
| 最近记录: |