我有另一个开发人员提供的C ++共享对象。我没有C ++代码,只有.so文件。我可以直接在Android应用程序中使用.so文件吗? 我已经完成了一些JNI编程,但它本身使用的是C ++代码而不是.so。我的问题是我没有C代码。有没有办法实现这个目标?
答案 0 :(得分:2)
是的,您可以在JNI应用程序中使用预编译的共享对象。首先,确保它是为正确的平台构建的。这涉及ABI,如x86或armeabi-v7a,但也涉及OS平台级别;为android-21构建的 .so 可能无法在android-19上加载。
其次,您需要一个Java类(或多个类)来描述共享对象公开的本机方法。不仅方法名称和签名必须正确,而且Java类名称和完整包名称也在 .so 中进行了硬编码。一些原生方法应该声明为静态,其他方法则不是。通常,底层的C代码并不关心。
从本机二进制文件反向设计这些方法签名可能非常棘手。但有时您可以简单地猜测,就像您看到导出的函数Java_com_example_hellojni_HelloJni_stringFromJNI
那样您需要提供Java类:
package com.example.hellojni;
public class HelloJni {
public native String stringFromJNI();
}
您不必担心私有与公开原生方法。 JNI忽略了这个属性。
共享对象可能期望Java端有一些回调。如果它在其中查找某个特定于应用程序的类和方法,并且您没有提供它,则该应用程序将崩溃。
答案 1 :(得分:1)
选项1是编写一个包装器库,其中Java本机方法访问.so。
的功能选项2正在使用JNA。如果您告诉它参数结构和返回类型,JNA可以访问任意库函数。根据接口的复杂程度,这可能很容易也可能不容易。在JNA项目的www文件夹中有Android的说明。
在这两种情况下,您都需要.so的相应头文件或至少详细的文档,因此您不必猜测参数类型。