【问题标题】:Loading a static void C function via AndroidfromJNI another Package将静态 void C 函数从另一个包加载到 Android
【发布时间】:2015-08-18 15:15:17
【问题描述】:

我正在尝试使用 JNI 做一些事情,结果发现了以下问题:

如果我想在 Java 中使用本机函数,我会通过

加载存储所需函数的所需库
static{
     System.loadLibrary("lib");
}

并使用

native private static int calculate(byte[] numberArray);

在java文件中声明本地方法。在程序本身中,我可以使用这个函数来计算一些东西:

int result = calculate(array);

这只有在我使用 javah 创建的头文件编译共享对象时才有效,以便每个函数在 c 端命名为:

static void Java_com_packagename_File_calculate(const void* array, void* result){
    code[...]
}

如果我删除 java 代码中对这个 c 函数的引用(“native [...] calculate[...]”);是否有可能通过java访问/执行仍然存在的c代码(当然不编辑现有文件;-)),例如通过反射或继承?或者有什么可能的:

public class NewClass{

  public int nativeCheater(){
    System.loadLibrary("lib");
    native private static int Java_com_packagename_File_calculate;
  }        
}

重要的是,我想使用一个与之前使用的包 com.packagename.(File) 没有任何关系的全新类。

提前致谢:-)

【问题讨论】:

    标签: java reflection android-ndk java-native-interface native-code


    【解决方案1】:

    不,但是您可以创建一个具有相同包和类名的新类并访问相同的本地方法。新类可以将此方法声明为 public。

    另一种方法是通过 Jni_OnLoad() 和 RegisterNatives() 使用动态绑定。这样,您的本机实现可以绑定到任何 Java 类,甚至多个。

    但是,如果您既无法访问 Java 类也无法访问本机源代码,则您始终可以在自己的类中创建自己的本机方法,并在 您的 C 中显式调用原始方法:

    static void Java_com_mypackagename_File_calculate(const void* array, void* result) {     
      Java_com_packagename_File_calculate(array, result);
    

    }

    【讨论】:

    • 感谢您的快速回复。我试图通过 URLClassLoader 添加一个新类,但我无法使用新类。如果我使用(加载后) Class.forName("com.package.File").getDeclaredMethods() 我收到一个包含旧文件方法的数组。你能提供一个代码示例吗?
    • 我不认为 Android JVM 允许两次加载具有相同全名的两个类。我的回答暗示你使用一个新的类而不是原来的。 RegisterNatives() 方法可行,但这需要访问本机代码。另一方面,如果您既无法访问 Java 类也无法访问本机源代码,我为您添加了第三种方法。
    猜你喜欢
    • 1970-01-01
    • 2016-02-06
    • 2023-01-28
    • 1970-01-01
    • 1970-01-01
    • 2012-11-09
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多