Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/205.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Android应用程序上加载现有共享库(.so)时出错(未找到未满足要求的LinkError本机方法)_Java_Android_C_Linux_Android Ndk - Fatal编程技术网

Java 在Android应用程序上加载现有共享库(.so)时出错(未找到未满足要求的LinkError本机方法)

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 $(

这是我的设想:

-)我有一个由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 $(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及其工作原理的信息。