Android NDK本机函数调用问题

Dae*_*den 1 android native android-ndk

我正在尝试编写一个使用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
Run Code Online (Sandbox Code Playgroud)

我的代码如下:

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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

谢谢!

Sev*_*yev 6

阅读JNI.简而言之,任意全局C函数都不能通过NDK从Java调用.为了可调用,函数需要一个非常特定的签名,类似于:

void Java_com_mypackage_MyClass_MyMethod(JNIEnv *jni, jobject thiz, jint arg1);
Run Code Online (Sandbox Code Playgroud)

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

native void MyMethod(int arg1);
Run Code Online (Sandbox Code Playgroud)

很明显,香草sqrt不适合这个账单.因此,您需要为要从Java调用的每个函数提供一个Java友好的包装器.考虑到这一点,您可能希望为仅仅是数学原语的更高级概念提供包装器.Java/C边界很乱; 你穿越越少越好.

此外,该库需要从专门针对Android的来源构建.NDK拥有相应的工具.另一个平台(比如Linux或Windows)的现成二进制文件将无法使用.

编辑:javahJDK 的工具可以带有一堆native声明的Java类,并使用虚拟实现制作骨架H/C文件.实质上,沿着JNI规则将方法原型从Java转换为C.

  • "Java/C边界很乱;越少越好,越好." 阿门. (2认同)