Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.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
调用静态方法的JNI。类对象是必需的吗? 开始使用JNI调用C++中的静态java方法。具体地说,在获得一个jclass(使用FindClass)和一个jmethodID(使用GetStaticMethodID)之后,我继续调用CallStatic*MethodA例程系列。事实证明,所有这些例程都将jclass作为第一个参数。我开始想为什么需要类对象:因为所有信息都是在GetStaticMethodID中提供的,所以类对象对于JVM完成任务似乎是不必要的。然后,我尝试调用这些例程,同时为第一个参数传递NULL,调用成功_Java_C++_Static_Java Native Interface - Fatal编程技术网

调用静态方法的JNI。类对象是必需的吗? 开始使用JNI调用C++中的静态java方法。具体地说,在获得一个jclass(使用FindClass)和一个jmethodID(使用GetStaticMethodID)之后,我继续调用CallStatic*MethodA例程系列。事实证明,所有这些例程都将jclass作为第一个参数。我开始想为什么需要类对象:因为所有信息都是在GetStaticMethodID中提供的,所以类对象对于JVM完成任务似乎是不必要的。然后,我尝试调用这些例程,同时为第一个参数传递NULL,调用成功

调用静态方法的JNI。类对象是必需的吗? 开始使用JNI调用C++中的静态java方法。具体地说,在获得一个jclass(使用FindClass)和一个jmethodID(使用GetStaticMethodID)之后,我继续调用CallStatic*MethodA例程系列。事实证明,所有这些例程都将jclass作为第一个参数。我开始想为什么需要类对象:因为所有信息都是在GetStaticMethodID中提供的,所以类对象对于JVM完成任务似乎是不必要的。然后,我尝试调用这些例程,同时为第一个参数传递NULL,调用成功,java,c++,static,java-native-interface,Java,C++,Static,Java Native Interface,我的问题是:用空类对象调用这些方法安全吗 激励因素是:如果它确实合法,我将不必缓存类对象以供后续调用静态方法(同时记住调用NewGlobalRef…)。缓存jmethodID就足够了。不,使用空(或无效)类指针调用此类静态函数绝对不安全 您的实践可能非常成功,例如,如果您的静态方法不引用任何其他静态类成员。但是,如果静态java方法引用任何其他静态成员,则JVM将需要有效的类指针 示例: 以这个简单的Java演示为例MyTest.Java: public class MyTest { p

我的问题是:用空类对象调用这些方法安全吗


激励因素是:如果它确实合法,我将不必缓存类对象以供后续调用静态方法(同时记住调用NewGlobalRef…)。缓存jmethodID就足够了。

不,使用空(或无效)类指针调用此类静态函数绝对不安全

您的实践可能非常成功,例如,如果您的静态方法不引用任何其他静态类成员。但是,如果静态java方法引用任何其他静态成员,则JVM将需要有效的类指针

示例:

以这个简单的Java演示为例
MyTest.Java

public class MyTest {
    public static void mymain() {
        System.out.println("Hello, World in java from mymain");
        System.out.println(magic_counter);   // this will cause a segfault if 
    }                                        // class pointer is null 
    private static int magic_counter=777; 
}

并调用以下JNI C++片段

... // JVM already loaded and initialised

jclass cls2 = env->FindClass("MyTest");
if(cls2 == nullptr) {
    cerr << "ERROR: class not found !";
}
else {
    cout << "Class MyTest found" << endl; 
    jmethodID mid = env->GetStaticMethodID(cls2, "mymain", "()V"); 
    if(mid == nullptr) 
        cerr << "ERROR: method void mymain() not found !" << endl; 
    else {
        env->CallStaticVoidMethod(cls2, mid);
        cout << endl;
    }
 }
..//JVM已经加载并初始化
jclass cls2=env->FindClass(“MyTest”);
if(cls2==nullptr){

cerr您不应该这样做,但重要的是要理解为什么在调用静态方法时,在某些情况下可以为类使用NULL…至少在某些实现中是这样。 我当然不是java或jni方面的专家,但如果您阅读源代码时非常清楚,android jni确实没有引用CallStatic*方法的对象参数

static jboolean CallStaticBooleanMethod(JNIEnv* env, jclass, jmethodID mid, ...)
唯一的问题是你不能保证所有平台上的行为,这只是一个可能实现的来源

提到该方法必须来自clazz,因此很可能其他实现在调用之前进行二次检查,即使这是java发布实现可能不会进行的性能权衡


值得注意的是,静态方法只能访问静态成员,因此此调用应该是安全的,但是jclass对象不是类的实例,而是类定义,它可以轻松用于诊断信息或其他与实际调用方法无关的内容。请确保安全并存储jclass对象,这样做实际上没有开销,因为它不是对象的实际实例。

Dalvik in
CallStatic\jname\jname\jname\35;方法
,因此它看起来确实好像传递
NULL
就可以了。不过,我不能对其他JVM说什么。JNI规范说这是必要的,所以这是必要的。我不会编写依赖于它只不过是因为你的静态方法不调用同一个类中的其他静态方法,也不使用静态类变量!我试过你的例子,没有Sebug。我在Linux上使用Oracle JDK/JRE 1.80.45来编写java,C++编译C++。你用的是什么JVM,在什么OS?BTW,我一定是失踪了。有些东西…我发现很难理解,一旦原生/java绑定已经被交叉,java代码被执行,JVM在运行时-仍然需要求助于在C++边上传递的类对象来解决嵌套的静态成员/方法……以确保……我将NULL传递给CaltStasoVoID方法。(NULL,mid),而不是GetStaticMethodID(cls2,“mymain”,“V”)…@user4212919好吧,我有相同的java版本,在64位模式下运行,但在windows 8.1和MSVC2013上运行。我可以使用NULL而不是cls2运行此示例,如果且仅当我注释掉了magic_数字的打印。@user4212919问题是存在调用约定,如果您不尊重它,则有它不起作用的风险。按cal从J++中获取JAVE方法,从C++中,您承担了java调用java函数所需的一些责任。因此,您必须确保调用函数从内部得到期望的结果。是的,在某些情况下,调用空静态方法时,使用NULL对类是安全的。“是的,可以将16个字节放入分配给
malloc()
”的两字节内存块中,因为在“某些实现”
malloc()中
内部使用最小大小为16字节的块。如果您链接的Dalvik实现更改为实际使用该
jclass
参数,您认为会发生什么情况?您真的认为可以将代码写入“现在可以了,谁关心未来?”"标准?我不是它的粉丝,但事实是,历史上许多程序在实现过程中都依赖于怪癖。这些怪癖可以变得众所周知,以至于供应商实际上坚持这种行为。我想进一步指出,大多数程序都包含某种对未记录行为的依赖,可能是无意的。情况类似的情况甚至导致主要软件供应商将错误/怪癖保留在适当的位置,以免大量现成的软件出现故障。此外,即使是主要的sun java hotspot也不使用参数see,其中不使用“receiver”,所有称其为pass NULL的位置都将其作为参数。处理文档的人可能很容易将参数描述更改为“此参数未使用,其值被忽略”,这样将来的每个人都不必再担心它。