Android NDK 原生函数调用问题 [英] Android NDK Native Function Call Issue

查看:23
本文介绍了Android NDK 原生函数调用问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to write an Android application that makes use of the GNU Scientific Library (GSL). In particular, I am interested in 'libgslcblas.so' for its BLAS implementation. I decided to take advantage of the Android NDK and write a Java program that loads the library and makes the appropriate function calls.

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

To test how this would work, I attempted to write a simple program that would load 'libm.so' and make an arbitrary function call. This seemed about a trivial a use-case of the NDK as I could think of, yet I ran into the following issue:

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 用法.有人可以帮我解决这个问题吗?

I really do not understand the problem. As I said, this is the simplest use of the NDK I can think of. Can someone help me resolve this issue?

谢谢!

推荐答案

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

Read up on JNI. In short, arbitrary global C functions are NOT callable from Java via NDK. 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);

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

On the Java side, that would be a method of class MyClass in package com.mypackage:

native void MyMethod(int arg1);

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

Obviosly, vanilla sqrt won't fit the bill. So you need to provide a Java-friendly wrapper for every function you intend to call from 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; the less you cross it, the better.

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

Also, the library needs to be built from sources specifically for Android. NDK has the tools for that. A ready-made binary for another platform (say, Linux or Windows) won't be usable.

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

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. Essentially, translate the method prototypes from Java to C along the JNI rules.

这篇关于Android NDK 原生函数调用问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆