Issue
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!
Solution
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.
Answered By - Seva Alekseyev
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.