I have a robot called the "Robotic Arm Edge" and the USB Interface. I am trying to make custom software, but this involves the Java Native Interface. I chose Java because it is much easier to make a gui interface in than the ATK+ library for C/C++. The reason I need the Java Native interface is libusb, which I already have a working controller for that I wrote myself. Now, all that I need to do is write a Java wrapper, but I need to convert a jstring to a c string. The GetStringUTFChars
JNI method always results in a fatal error, and I have tried almost every variation of the method possible. This is the Java class:
RoboController.java:
package arm.robot;
import arm.robot.enums.*;
public class RoboController {
static {
System.loadLibrary("robojava");
sendToRobo0("");
}
static Pinchers m1 = Pinchers.stopped;
static Joint m2 = Joint.stopped;
static Joint m3 = Joint.stopped;
static Joint m4 = Joint.stopped;
static Base m5 = Base.stopped;
static Light l = Light.off;
private static native boolean sendToRobo0(String cmds);
public static void sendToRobo(){
StringBuilder sb = new StringBuilder("");
boolean first = true;
if(m1.equals(Pinchers.opening)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("m1o");
}
else if(m1.equals(Pinchers.closing)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("m1c");
}
if(m2.equals(Joint.up)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("m2u");
}
else if(m2.equals(Joint.down)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("m2d");
}
if(m3.equals(Joint.up)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("m3u");
}
else if(m3.equals(Joint.down)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("m3d");
}
if(m4.equals(Joint.up)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("m4u");
}
else if(m4.equals(Joint.down)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("m4d");
}
if(m5.equals(Base.clockwise)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("m5cw");
}
else if(m5.equals(Base.counterclockwise)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("m5ccw");
}
if(l.equals(Light.on)) {
if(!first){
sb.append(" ");
}
else first = false;
sb.append("lon");
}
sendToRobo0(sb.toString());
}
}
The header from javah
:
arm_robot_RoboController.h
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class arm_robot_RoboController */
#ifndef _Included_arm_robot_RoboController
#define _Included_arm_robot_RoboController
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: arm_robot_RoboController
* Method: sendToRobo0
* Signature: (Ljava/lang/String;)Z
*/
JNIEXPORT jboolean JNICALL Java_arm_robot_RoboController_sendToRobo0
(JNIEnv *, jclass, jstring);
#ifdef __cplusplus
}
#endif
#endif
And finally, the implementation, where the fatal error occurs:
arm_robot_RoboController.cpp
#include <jni.h>
#include <string>
#include <iostream>
#include "arm_robot_RoboController.h"
using namespace std;
JNIEXPORT jboolean JNICALL Java_arm_robot_RoboController_sendToRobo0(JNIEnv* env, jclass c, jstring args){
const char *str= env->GetStringUTFChars(args,(jboolean*)0); //FATAL ERROR HERE
//string s(str);
//cout << s;
return true;
}
Error log:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0xb676a978, pid=2912, tid=2842113136
#
# JRE version: Java(TM) SE Runtime Environment (7.0_40-b43) (build 1.7.0_40-b43)
# Java VM: Java HotSpot(TM) Client VM (24.0-b56 mixed mode linux-arm )
# Problematic frame:
# V [libjvm.so+0x262978] jni_GetStringUTFChars+0x74
#
# Core dump written. Default location: /home/pi/robotic arm/gui/core or core.2912
#
# An error report file with more information is saved as:
# /home/pi/robotic arm/gui/hs_err_pid2912.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.sun.com/bugreport/crash.jsp
#
Aborted (core dumped)
The build command line I use:
g++ -c -I"/usr/lib/jvm/jdk-7-oracle-armhf/include" -I"/usr/lib/jvm/jdk-7-oracle-armhf/include/linux" robo.cpp
g++ -I"/usr/lib/jvm/jdk-7-oracle-armhf/include" -I"/usr/lib/jvm/jdk-7-oracle-armhf/include/linux" -olibrobojava.so -shared -Wl,-soname,robojava.so arm_robot_RoboController.cpp robo.o
I am using a Raspberry Pi Model B running close to the latest Raspbian Wheezy.
I cannot fing out what I am doing wrong.