Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何从OSGi包中的类获取JNI中的jclass_Java_C++_Java Native Interface_Osgi - Fatal编程技术网

Java 如何从OSGi包中的类获取JNI中的jclass

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*) "

在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*) "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;