【问题标题】:Class name from jclass in JNIJNI中jclass的类名
【发布时间】:2012-02-13 17:58:39
【问题描述】:

这可能是一个愚蠢的问题,表明对 JNI 缺乏了解。我正在编写一个封装 Java VM 的 C++ 程序:我正在使用诸如 CallVoidMethod 之类的调用来调用 VM 中的函数。这纯粹是背景,与问题不太相关。

我希望能够找到给定 jclass 实例的 Java 类的名称。有没有办法做到这一点?我可以像在 Java 程序中那样调用 GetName 函数吗?

【问题讨论】:

    标签: java-native-interface


    【解决方案1】:

    jclass 实例是将调用方法的对象;您需要在Class 类上查找getName 方法ID,然后使用CallObjectMethodjclass 实例上调用它以获得jstring 结果。

    简而言之,是的,您只需调用getName 函数并查看jstring 结果。

    编辑

    (省略错误处理)

    JNIEnv* env = ...;
    // substitute your desired class's specifier for "java/lang/Class"...
    jclass cls = env->FindClass("java/lang/Class"); 
    jmethodID mid_getName = env->GetMethodID(cls, "getName", "()Ljava/lang/String;");
    jstring name = env->CallObjectMethod(cls, mid_getName);
    

    【讨论】:

    • 很抱歉,由于这个问题的嵌套元性质,我的大脑在读取您的答案时才开始自食其力。能否展示一个简单的代码示例?
    • 看起来很有希望,但在为我调用 GetMethodID 后 env->ExceptionOccurred() 为真
    • 我认为这可能更接近于寻求的答案:stackoverflow.com/questions/12719766/…
    • 我觉得代码不太对。如果您有一个 jclass 对象 myJClass,那么您仍然需要获取 java.lang.Class 的 jclass 对象,并在其上查找 getName() 方法。因此,您需要两个 jclass 对象:一个是您开始使用的(在我上面的示例中为 myJClass),另一个是表示 java.lang.class。您将后者传递给 GetMethodID(),将前者传递给 CallObjectMethod()。
    • 谢谢@MartinC.Martin。如您所述,我需要先使用getClass(),然后再使用getName()。在它不起作用之前。 :\
    【解决方案2】:

    受公认答案的启发,我提出了一个适合我的目的的函数

    /**
     * JNI/C++: Get Class Name
     * @param env [in] JNI context
     * @param myCls [in] Class object, which the name is asked of
     * @param fullpath [in] true for full class path, else name without package context
     * @return Name of class myCls, encoding UTF-8
     */
    std::string getClassName(JNIEnv* env, jclass myCls, bool fullpath)
    {
        jclass ccls = env->FindClass("java/lang/Class");
        jmethodID mid_getName = env->GetMethodID(ccls, "getName", "()Ljava/lang/String;");
        jstring strObj = (jstring)env->CallObjectMethod(myCls, mid_getName);
        const char* localName = env->GetStringUTFChars(strObj, 0);
        std::string res = localName;
        env->ReleaseStringUTFChars(strObj, localName);
        if (!fullpath)
        {
            std::size_t pos = res.find_last_of('.');
            if (pos!=std::string::npos)
            {
                res = res.substr(pos+1);
            }
        }
        return res;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 1970-01-01
      • 2014-09-13
      • 1970-01-01
      • 2011-02-05
      相关资源
      最近更新 更多