JNI:给定jobject,获取其缓存方法

时间:2013-02-07 12:44:24

标签: java c++ caching optimization java-native-interface

在Java中,我有一个界面:

public interface I {...}

声明一个函数void f()和一些类:

public class A implements I {...}
public class B implements I {...}
public class C implements I {...}
...

我经常调用本机函数:

public native void nativeFunc(I obj);

在C ++中,我获得了

jobject jobj

目的是致电

jobj.f();

每次都没有通过链

cls = jenv->GetObjectClass(jobj);           (1)
mid = jenv->GetMethodID(cls, "f", "()V");   (2)
jenv->CallVoidMethod(jobj, mid);            (3)

我似乎无法在本机调用之间缓存mid。作为另一个建议,我可以从第(1)行开始,然后使用缓存的map <jclass, jmethodID>。但是,这可能也不会起作用,因为jclass引用可能因同一个类而不同。

有优化解决方案吗?

2 个答案:

答案 0 :(得分:0)

根据程序的性质和实现“接口I”的类的数量,以及可用的类加载器的数量(可以乘以类的数量),您可以决定创建对这些类的全局引用

jclass globalRefCls = jni->NewGlobalRef(localRefCls);

然后,您可以将这些实例和jmethodID缓存在地图中供以后使用。

更新

在评论中发言后,我重新阅读了您的要求 只要你每次都得到一个jobject,你需要得到jclass 无论如何,你的地图也可以映射到字符串是该类的描述符。

每当你得到一个jobject时,提取jclass并询问它的名字(你可以缓存java / lang / Class getName方法)。

你也可以在你想要的前面创建这个缓存​​,因为你知道期望哪些对象(那些实现我)

话虽如此,我猜它不会像检查IsSameObject那样高效。

答案 1 :(得分:0)

我能想到的一个解决方案是将类A, B, C, ...的{​​{1}}引用缓存到任何数据结构中(数组,列表,等等; map在这里没有加速)。我们将这个结构称为存储。然后我可以优化步骤(2)并拥有以下链:

jclass

即。我用JNI

(1) ... (obtain jcls)
(2) for(jclass jclsStored : Storage) {
        if(IsSameObject(jcls, jclsStored))
        {
            mid = ...;
            classFound = true;
        }
    }
    if(!classFound)
        Storage.add(necessary info);
(3) ...            

用于绕过同一类的不同IsSameObject() 值。如果jclass很快,则会进行优化。