I'm having problem with this JNI thing...
I'm dealing with an FPGA and an Android device, and to make them communicate I use JNI library. There is 7-segment Controller in FPGA and Android-to-FPGA driver also.
But I found myself stuck in this implementation hell... and yes, I searched and searched. But most answer was "Look for the naming convention" or "Make sure you are referring .so file". I think I'm not in that case...
First here is my .java android code :
package com.hanback.segment;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class SegmentActivity extends Activity {
private int CountNumber;
private int flag = 0;
private boolean stop = false;
static{ System.loadLibrary("7segment"); }
public native int SegmentControl(int data);
public native int SegmentStateControl(int data);
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_segment);
CountNumber = 0;
SegmentControl(0);
final Button Start = (Button) findViewById(R.id.butStart);
final Button Set = (Button) findViewById(R.id.butSet);
final Button Stop = (Button) findViewById(R.id.butStop);
final EditText Ctno = (EditText) findViewById(R.id.etCountNo);
Start.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
if (Ctno.getText().toString().getBytes().length <= 0) {
Toast.makeText(getApplicationContext(), R.string.error_ctrnotset,
Toast.LENGTH_SHORT).show();
return;
}
else if (CountNumber <= 0 || CountNumber >= 1000000){
Toast.makeText(getApplicationContext(), R.string.error_ctrvalerr,
Toast.LENGTH_SHORT).show();
return;
}
SegmentStateControl(1);
}
});
Set.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
if (Ctno.getText().toString().getBytes().length <= 0) {
Toast.makeText(getApplicationContext(), R.string.error_ctrnotset,
Toast.LENGTH_SHORT).show();
return;
}
else
CountNumber = Integer.parseInt(Ctno.getText().toString());
if (CountNumber <= 0 || CountNumber >= 1000000){
Toast.makeText(getApplicationContext(), R.string.error_ctrvalerr,
Toast.LENGTH_SHORT).show();
return;
}
CountNumber = Integer.parseInt(Ctno.getText().toString());
SegmentStateControl(0);
SegmentControl(CountNumber);
}
});
Stop.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
SegmentStateControl(0);
}
});
}
}
Then c code : (header skipped)
extern "C"{
jint Java_com_hanback_segment_SegmentActivity_SegmentControl(JNIEnv* env, jobject thiz, jint data) {
int dev, ret;
dev = open("/dev/segment",O_RDWR | O_SYNC);
if(dev != -1) {
ret = write(dev, &data, 4); // write is pre-defined FPGA driver function
close(dev);
} else {
__android_log_print(ANDROID_LOG_ERROR, "SegmentActivity", "Device Open ERROR!\n");
exit(1);
}
return 0;
}
jint Java_com_hanback_segment_SegmentActivity_SegmentStateControl(JNIEnv* env, jobject thiz, jint data) {
int dev, ret;
dev = open("/dev/segment". O_RDWR | O_SYNC);
if(dev != 1) {
ret = ioctl(dev, data, NULL, NULL); // ioctl is pre-defined FPGA driver function
close(dev);
} else {
__android_log_print_(ANDROID_LOG_ERROR, "SegmentActivitiy", "Device Open ERROR!\n");
exit(1);
}
}
}
And Android.mk and Application.mk has no error...
Finally Logcat error message :
01-01 15:07:02.429: D/dalvikvm(1318): Trying to load lib /data/data/com.hanback.segment/lib/lib7segment.so 0x40514760
01-01 15:07:02.429: D/dalvikvm(1318): Added shared lib /data/data/com.hanback.segment/lib/lib7segment.so 0x40514760
01-01 15:07:02.429: D/dalvikvm(1318): No JNI_OnLoad found in /data/data/com.hanback.segment/lib/lib7segment.so 0x40514760, skipping init
01-01 15:07:02.449: W/dalvikvm(1318): No implementation found for native Lcom/hanback/segment/SegmentActivity;.SegmentControl (I)I
01-01 15:07:02.457: D/AndroidRuntime(1318): Shutting down VM
01-01 15:07:02.457: W/dalvikvm(1318): threadid=1: thread exiting with uncaught exception (group=0x40015560)
01-01 15:07:02.460: E/AndroidRuntime(1318): FATAL EXCEPTION: main
01-01 15:07:02.460: E/AndroidRuntime(1318): java.lang.UnsatisfiedLinkError: SegmentControl
01-01 15:07:02.460: E/AndroidRuntime(1318): at com.hanback.segment.SegmentActivity.SegmentControl(Native Method)
01-01 15:07:02.460: E/AndroidRuntime(1318): at com.hanback.segment.SegmentActivity.onCreate(SegmentActivity.java:40)
01-01 15:07:02.460: E/AndroidRuntime(1318): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
01-01 15:07:02.460: E/AndroidRuntime(1318): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
01-01 15:07:02.460: E/AndroidRuntime(1318): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
01-01 15:07:02.460: E/AndroidRuntime(1318): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
01-01 15:07:02.460: E/AndroidRuntime(1318): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
01-01 15:07:02.460: E/AndroidRuntime(1318): at android.os.Handler.dispatchMessage(Handler.java:99)
01-01 15:07:02.460: E/AndroidRuntime(1318): at android.os.Looper.loop(Looper.java:130)
01-01 15:07:02.460: E/AndroidRuntime(1318): at android.app.ActivityThread.main(ActivityThread.java:3683)
01-01 15:07:02.460: E/AndroidRuntime(1318): at java.lang.reflect.Method.invokeNative(Native Method)
01-01 15:07:02.460: E/AndroidRuntime(1318): at java.lang.reflect.Method.invoke(Method.java:507)
01-01 15:07:02.460: E/AndroidRuntime(1318): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-01 15:07:02.460: E/AndroidRuntime(1318): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-01 15:07:02.460: E/AndroidRuntime(1318): at dalvik.system.NativeStart.main(Native Method)
I'm a beginner for JNI and this has blown my 1.5 days... Please help me T_T
答案 0 :(得分:1)
声明你的功能:
This is the first time this instance runs
this is not really a new instance
JNIEXPORT宏用于使您的函数在.so文件的动态表中可见,以便Java可以在运行时链接它们。 JNICALL用于声明调用约定。