Android NDK 原生函数调用问题

标签 android android-ndk native

我正在尝试编写一个使用 GNU 科学库 (GSL) 的 Android 应用程序。特别是,我对“libgslcblas.so”感兴趣,因为它的 BLAS 实现。我决定利用 Android NDK 并编写一个 Java 程序来加载库并进行适当的函数调用。

为了测试这将如何工作,我尝试编写一个简单的程序来加载“libm.so”并进行任意函数调用。正如我所想,这似乎是 NDK 的一个微不足道的用例,但我遇到了以下问题:

07-05 18:11:07.264: I/System.out(1298): debugger has settled (1464)
07-05 18:11:07.583: D/dalvikvm(1298): No JNI_OnLoad found in /system/lib/libm.so 0x41345988, skipping init
07-05 18:11:07.903: W/dalvikvm(1298): No implementation found for native Lissm/libctest/LibCtest;.sqrt (D)D

我的代码如下:

package issm.libctest;

import android.os.Bundle;
import android.app.Activity;
import android.widget.TextView;

public class LibCtest extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        TextView  tv = new TextView(this);
        setContentView(R.layout.activity_lib_ctest);

        double x = sqrt(4);

        tv.setText( "Sine of: " + x);
        setContentView(tv);
    }

    public native double sqrt(double x);

    static
    {
        System.load("/system/lib/libm.so");
    }
}

我真的不明白这个问题。正如我所说,这是我能想到的最简单的 NDK 用法。有人可以帮我解决这个问题吗?

谢谢!

最佳答案

阅读 JNI。简而言之,不能通过 NDK 从 Java 调用任意全局 C 函数。为了可以调用,函数需要一个非常具体的签名,如下所示:

void Java_com_mypackage_MyClass_MyMethod(JNIEnv *jni, jobject thiz, jint arg1);

在 Java 方面,这将是包 com.mypackage 中的类 MyClass 的方法:

native void MyMethod(int arg1);

显然,vanilla sqrt 不符合要求。因此,您需要为打算从 Java 调用的每个函数提供一个 Java 友好的包装器。考虑到这一点,您可能希望为更高级的概念提供包装器,而不仅仅是数学原语。 Java/C边界杂乱;你穿过它的次数越少越好。

此外,该库需要从专门针对 Android 的源代码构建。 NDK 有这方面的工具。用于其他平台(例如 Linux 或 Windows)的现成二进制文件将无法使用。

编辑:来自 JDK 的 javah 工具可以采用带有一堆 native 声明的 Java 类,并制作带有虚拟实现的框架 H/C 文件。本质上,按照 JNI 规则将方法原型(prototype)从 Java 转换为 C。

关于Android NDK 原生函数调用问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11354411/

相关文章:

android - 在Android中使用Opencv进行边缘检测

reactjs - 我想在初始屏幕 React Native 中播放 lottie 动画

android - Google Drive API 不能很好地与 ProGuard (NPE) 配合使用

android - 死函数不会从 Android NDK 构建的共享对象中删除

Android-如何在 AlertDialog 中使用 Spinner?

android - Crashlytics NDK 符号和 Gradle 任务

kotlin - 如何控制kotlin-native的 “native dependency”下载的目标目录?

c++ - 用于 Native C++ 应用程序的 GUI 库

Android 将当前的 Fragment 类转换为 Activity 类

Delphi v10.2.2 升级到 v10.2.3 后 Android 库 "Revert System Files to Default"破坏编译