Java 如何从OSGi包中的类获取JNI中的jclass
在C/C++中,您需要一个Java 如何从OSGi包中的类获取JNI中的jclass,java,c++,java-native-interface,osgi,Java,C++,Java Native Interface,Osgi,在C/C++中,您需要一个jclass值,以便使用声明的native方法向Java类注册本机函数 考虑以下Java类: public class Native { public native int f(int i); } < >登记一个本地C++/C++函数,用于本地(f-)>代码>,我们需要在C++侧调用: JNIEnv* env = ...; jclass nativeClass = ...; JNINativeMethod nativeMethod = { (char*) "
jclass
值,以便使用声明的native
方法向Java类注册本机函数
考虑以下Java类:
public class Native {
public native int f(int i);
}
< >登记一个本地C++/C++函数,用于<代码>本地(f-)>代码>,我们需要在C++侧调用:
JNIEnv* env = ...;
jclass nativeClass = ...;
JNINativeMethod nativeMethod = {
(char*) "f",
(char*) "(I)I",
(void*) Java_org_example_Native_f // The native C function
};
env->RegisterNatives(nativeClass, &nativeMethod, 1);
有问题的部分是,如果无法从默认类加载器访问类,则获取jclass
值。如果类Native
位于加载在JVM内运行的OSGi容器(例如Equinox)内的OSGi包中,则情况并非如此
为了访问该类,我使用Java函数返回我的类的class
实例:
public class Helper {
public static Class<?> getNativeClass() {
// Find bundle from system bundle context.
Bundle bundle = ... // details left out.
return bundle.loadClass("org.example.Native");
}
}
问题是我们确实需要一个“jclass”值(而不是jobject
值)。为了得到它,我实例化了我的Native
类的一个对象,并从中获得jclass
// This is the jclass for 'java.lang.Class<>'.
jclass classClass = env->GetObjectClass(nativeClassInstance);
// Now get the method id for function 'newInstance()'
jmethodId newInstanceMid = env->GetMethodID(helperClass,
"newInstance",
"()Ljava/lang/Object;");
// Instantiate our 'Native' class calling 'Class<Native>.newInstance()'.
jobject nativeInstance = env->CallObjectMethod(classClass,
nativeClassInstance,
newInstanceMid);
// Now, I can get the desired 'jclass' of my 'Native' class.
jclass nativeClass = env->GetObjectClass(nativeInstance);
//这是“java.lang.Class”的jclass。
jclass classClass=env->GetObjectClass(nativeClassInstance);
//现在获取函数“newInstance()”的方法id
jmethodId newInstanceId=env->GetMethodID(helperClass,
“新实例”,
“()Ljava/lang/Object;”;
//实例化调用“class.newInstance()”的“本机”类。
jobject nativeInstance=env->CallObjectMethod(classClass,
nativeClassInstance,
新实例ID);
//现在,我可以得到我的“原生”类所需的“jclass”。
jclass nativeClass=env->GetObjectClass(nativeInstance);
但这只起作用,因为我可以实例化我的Native
类
如何获得所需的
jclass
而不必实例化本机类的对象?您应该能够使用class
类型的jobject
,它是由助手方法返回的jclass
对象,只需强制转换即可:
jclass nativeClass = (jclass)nativeClassInstance;
我不明白这个问题。如果该类具有本机方法,则在Java执行的正常过程中加载它应该会导致执行其静态初始化方法中的System.loadLibrary()调用,这将自动注册其自身的本机函数。为什么你要做这件事?因为我有一个静态链接的C++服务器(包括Win32的跨平台),在其中我想嵌入一个JVM(在JVM里面,我需要运行OSGi)。在Win32中,混合静态和动态链接C/C++运行库LIB不是一个好主意,所以我的本机实现需要静态链接到C++应用程序。我没有意识到jclass
只是jobject
的一个子类,就像jstring
一样。我还尝试使用dynamic_cast(…)
(阅读了您的回复后),但意识到jobject
和jclass
不是多态的,因为(出于效率原因,我想)没有虚拟方法,甚至没有析构函数。
jclass nativeClass = (jclass)nativeClassInstance;