简体   繁体   English

Android NDK本机函数调用问题

[英]Android NDK Native Function Call Issue

I am attempting to write an Android application that makes use of the GNU Scientific Library (GSL). 我正在尝试编写一个使用GNU科学库(GSL)的Android应用程序。 In particular, I am interested in 'libgslcblas.so' for its BLAS implementation. 我尤其对'libgslcblas.so'的BLAS实现感兴趣。 I decided to take advantage of the Android NDK and write a Java program that loads the library and makes the appropriate function calls. 我决定利用Android NDK并编写一个Java程序来加载该库并进行适当的函数调用。

To test how this would work, I attempted to write a simple program that would load 'libm.so' and make an arbitrary function call. 为了测试其工作方式,我尝试编写一个简单的程序来加载“ libm.so”并进行任意函数调用。 This seemed about a trivial a use-case of the NDK as I could think of, yet I ran into the following issue: 我可以想到,这似乎是一个简单的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

My code is as follows: 我的代码如下:

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");
    }
}

I really do not understand the problem. 我真的不明白这个问题。 As I said, this is the simplest use of the NDK I can think of. 如我所说,这是我能想到的最简单的NDK使用方法。 Can someone help me resolve this issue? 有人可以帮我解决这个问题吗?

Thanks! 谢谢!

Read up on JNI. 阅读JNI。 In short, arbitrary global C functions are NOT callable from Java via NDK. 简而言之,不能通过NDK从Java调用任意全局C函数。 In order to be callable, a function needs a very specific signature, along the lines of: 为了可调用,一个函数需要一个非常特定的签名,大致如下:

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

On the Java side, that would be a method of class MyClass in package com.mypackage : 在Java方面,这将是com.mypackage包中MyClass类的方法:

native void MyMethod(int arg1);

Obviosly, vanilla sqrt won't fit the bill. 显然,香草sqrt不适合该法案。 So you need to provide a Java-friendly wrapper for every function you intend to call from Java. 因此,您需要为要从Java调用的每个函数提供一个Java友好的包装器。 With that in mind, you'll probably want to provide wrappers for higher-level concepts that mere math primitives. 考虑到这一点,您可能希望为仅数学基元的高级概念提供包装。 The Java/C border is messy; Java / C边界杂乱无章; the less you cross it, the better. 越少越好。

Also, the library needs to be built from sources specifically for Android. 另外,该库需要从专门用于Android的源构建。 NDK has the tools for that. NDK具有用于该目的的工具。 A ready-made binary for another platform (say, Linux or Windows) won't be usable. 用于其他平台(例如Linux或Windows)的现成二进制文件将无法使用。

EDIT: The javah tool from JDK can take a Java class with a bunch of native declarations and make skeleton H/C files with dummy implementations. 编辑:来自JDK的javah工具可以采用带有一堆native声明的Java类,并使用伪实现来制作骨架H / C文件。 Essentially, translate the method prototypes from Java to C along the JNI rules. 本质上,按照JNI规则将方法原型从Java转换为C。

确保您要使用的库(及其依赖项)是针对目标平台(Android Native平台)构建的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM