Java 在Android应用程序上加载现有共享库(.so)时出错(未找到未满足要求的LinkError本机方法)
这是我的设想: -)我有一个由ndk build生成的名为libpsp.so的共享库。这个库是使用大约30个.c文件生成的 Android.mk使用:Java 在Android应用程序上加载现有共享库(.so)时出错(未找到未满足要求的LinkError本机方法),java,android,c,linux,android-ndk,Java,Android,C,Linux,Android Ndk,这是我的设想: -)我有一个由ndk build生成的名为libpsp.so的共享库。这个库是使用大约30个.c文件生成的 Android.mk使用: LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # Here we give our module name and source file(s) LOCAL_MODULE := psp LOCAL_SRC_FILES := (My .c files) include $(
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Here we give our module name and source file(s)
LOCAL_MODULE := psp
LOCAL_SRC_FILES := (My .c files)
include $(BUILD_SHARED_LIBRARY)
-)ndk build自动将libpsp.so放在dir/libs/armeabi中
-)在我的Java代码中,我有:
private native int calculateCoefficient(double w, double v_st_e_prev, double c_l);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
**//Loads successfully
System.loadLibrary("psp");**
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
TextView lv = (TextView)findViewById(R.id.textView);
**//Returns an error: unsatisfiedlinkerror native method not found
lv.setText(Integer.toString(calculateCoefficient(1,1,1)));**
}
-)用于构建共享库的.c文件之一具有CalculateCoefficive方法,其签名为:
sint32_t calculateCoefficient(double_t w, double_t v_st_e_prev, double_t *c_l);
那么,如果.So库中存在calculateCoefficient方法,为什么Android找不到它呢?我刚开始与NDK合作,很抱歉,如果我错过了一些显而易见的东西,但我做了一些研究,我找不到这个问题的答案
更新1:我没有访问实际代码的权限,库是由其他人生成的,我所拥有的只是带有方法签名的.h文件。因此,我无法编辑用于创建库的.c文件。您的签名错误。它需要是JNIEXPORT int JNICALL Java_classname_methodname(JNIENV*env,jobject obj,…),其中。。。是您实际想要传递的参数。指针不能被传递,如果你想要一个数组,你将使用jdoublearray,如果你只想通过引用传递一个double,你需要传递一个包含double的类,并在对象上设置该字段。首先,使用带有-d标志的ndk objdump来反汇编你的数组。因此,将其grep作为函数名来找出实际存在的内容。接下来,使用隐式根emulator的adb外壳,或者在设备上使用带有调试构建的run as工具,以检查安装并查看实际解包的内容。签名是从我有权访问的头文件中获得的,但我无法更改C代码和方法签名。抱歉,我先前的评论部分是错误的。缺少的Java_classname_etc前缀确实可以解释这个问题。如果无法修复当前库,那么编写一个新库,其中包含正确命名的jni兼容函数,用于包装和调用现有库。首先加载现有库,然后加载包装器。因此,我必须为我要调用的每个函数创建一个带有JNI函数的.c文件?是的。确切的方法名称和签名需要匹配。这就是Java知道调用什么的原因。但是在现有的C库和Java之间编写一个包装层是很常见的。创建一个标记为native method的Java方法,然后让JNI头生成器“javah”从Java文件生成正确的.h文件。您应该阅读更多关于JNI及其工作原理的信息。