2

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.

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

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. Can someone help me resolve this issue?

Thanks!

Daeden
  • 481
  • 1
  • 6
  • 20
  • You will want to use [JNI](http://developer.android.com/guide/practices/jni.html) to call native functions that you have recompiled with the NDK. – Keith Flower Jul 06 '12 at 00:57
  • @KeithFlower there is zero reference to the library in question... – t0mm13b Jul 06 '12 at 01:02
  • 2
    Yep. I'm talking about his global goal which I thought was calling functions in the GSL, not his test using libm.so (which ain't gonna work). – Keith Flower Jul 06 '12 at 01:08
  • @t0mm13b he is trying to use a third party library and certainly not trying to find square root of a number. The library he is trying to use "libgslcblas" might not be built for arm-eabi. loading "libm" might be typo or incorrect; – Tatvamasi Jul 06 '12 at 01:13
  • I think user was trying to test his understanding of how calling native functions might work by making what he intended to be a call to `sqrt()` in `libm.so`. My comment was about his overall goal, which I believe (as you note) will require recompiling GSL for arm-eabi, then calling desired functions via the JNI. – Keith Flower Jul 06 '12 at 01:18
  • The overall goal is to call GSL functions, but I have compiled GSL by generating a stand-alone tool chain. I've been able to push the lib in question to an emulated device and have successfully ran some tests, but now I want to to call GSL functions from the context of an App. – Daeden Jul 06 '12 at 01:23
  • You're getting there, but you'll have to use JNI to make those calls. See the link I provided in my first comment, and Seva's answer below. – Keith Flower Jul 06 '12 at 01:25
  • Here's a more general [JNI guide](http://java.sun.com/docs/books/jni/html/jniTOC.html) - the link I provided above is more specific to JNI in the Android environment. – Keith Flower Jul 06 '12 at 01:35
  • I will definitely bookmark that link Keith! Much obliged man! – Daeden Jul 06 '12 at 01:36

2 Answers2

7

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

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

native void MyMethod(int arg1);

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.

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.

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

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
1

make sure the library you are trying to use (and its dependencies) are built for target platform (Android Native platform).

Tatvamasi
  • 2,537
  • 19
  • 14
  • The reason I downvoted you was in the clue in the logcat - "No JNI_OnLoad found in /system/lib/libc.so" which the `libm` is linked in with the standard C library. – t0mm13b Jul 06 '12 at 00:58