Using JNI to send a String to JAVA from OF side?

#1

Hi! been trying to send data from OF to JAVA side, here is my code so far but is crashing, some one has done it before?

Code so far:

ofAndroid.java

public void setStringFromCppSide(String message) {

		Log.d("myTag", "This is my message");
	}

ofApp.h


  void sendStringtoJava(string message);

ofApp.cpp

void ofApp::update(){
sendStringtoJava("jala");
}
void ofApp::sendStringtoJava(std::string message) {
    jstring jStringParam = ofGetJNIEnv()->NewStringUTF(message.c_str());
    ofGetJNIEnv()->CallVoidMethod(ofGetOFActivityObject(), ofGetJNIEnv()->GetMethodID(ofGetJavaOFAndroid(), "setStringFromCppSide", "(Ljava/lang/String;)V"), jStringParam); //"setStringFromCppSide" is the name of a void of ofAndroid.java
    ofGetJNIEnv()->DeleteLocalRef(jStringParam);
}

This is the crash report in log cat:
Guess this is the error :

runtime.cc:582] JNI DETECTED ERROR IN APPLICATION: can’t call void cc.openframeworks.OFAndroid.setStringFromCppSide(java.lang.String) on instance of cc.openframeworks.androidMultiOFActivitiesExample.OFActivityA

#2

This is the crash report in log cat:
Guess this is the error :

runtime.cc:582] JNI DETECTED ERROR IN APPLICATION: can’t call void cc.openframeworks.OFAndroid.setStringFromCppSide(java.lang.String) on instance of cc.openframeworks.androidMultiOFActivitiesExample.OFActivityA

08-26 14:05:09.873 21873-21994/cc.openframeworks.androidMultiOFActivitiesExample A/tivitiesExampl: runtime.cc:582] in call to CallVoidMethodV
runtime.cc:582] from void cc.openframeworks.OFAndroid.render()
runtime.cc:582] “GLThread 181” prio=5 tid=21 Runnable
runtime.cc:582] | group=“main” sCount=0 dsCount=0 flags=0 obj=0x14f00e40 self=0xd4912a00
runtime.cc:582] | sysTid=21994 nice=8 cgrp=default sched=0/0 handle=0xd15bf970
runtime.cc:582] | state=R schedstat=( 22306334586 40137504 886 ) utm=2054 stm=176 core=5 HZ=100
runtime.cc:582] | stack=0xd14bc000-0xd14be000 stackSize=1042KB
runtime.cc:582] | held mutexes= “mutator lock”(shared held)
runtime.cc:582] native: #00 pc 002da4af /system/lib/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits>&, int, BacktraceMap*, char const*, art::ArtMethod*, void*, bool)+134)
runtime.cc:582] native: #01 pc 003703bb /system/lib/libart.so (art::thread::DumpStack(std::__1::basic_ostream<char, std::__1::char_traits>&, bool, BacktraceMap*, bool) const+210)
runtime.cc:582] native: #06 pc 000c7417 /system/lib/libart.so (art::(anonymous namespace)::ScopedCheck::CheckMethodAndSig(art::ScopedObjectAccess&, _jobject*, _jclass*, _jmethodID*, art::Primitive::Type, art::InvokeType)+1362)
runtime.cc:582] native: #07 pc 000c6087 /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, std::__va_list, art::Primitive::Type, art::InvokeType)+534)
runtime.cc:582] native: #08 pc 000b7a7d /system/lib/libart.so (art::(anonymous namespace)::CheckJNI::CallVoidMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+44)
runtime.cc:582] native: #09 pc 000ce918 /data/app/cc.openframeworks.androidMultiOFActivitiesExample-Jl6A2NWxdhhztRx44kfvHg==/lib/arm/libOFAndroidApp.so (_JNIEnv::CallVoidMethod(_jobject*, _jmethodID*, …)+92)
runtime.cc:582] native: #14 pc 00327d3c /data/app/cc.openframeworks.androidMultiOFActivitiesExample-Jl6A2NWxdhhztRx44kfvHg==/lib/arm/libOFAndroidApp.so (???)
runtime.cc:582] native: #15 pc 00327c04 /data/app/cc.openframeworks.androidMultiOFActivitiesExample-Jl6A2NWxdhhztRx44kfvHg==/lib/arm/libOFAndroidApp.so (???)
runtime.cc:582] native: #18 pc 002059d8 /data/app/cc.openframeworks.androidMultiOFActivitiesExample-Jl6A2NWxdhhztRx44kfvHg==/lib/arm/libOFAndroidApp.so (???)
runtime.cc:582] native: #21 pc 001ab624 /data/app/cc.openframeworks.androidMultiOFActivitiesExample-Jl6A2NWxdhhztRx44kfvHg==/lib/arm/libOFAndroidApp.so (Java_cc_openframeworks_OFAndroid_render+2168)
runtime.cc:582] native: #22 pc 00413c79 /system/lib/libart.so (art_quick_generic_jni_trampoline+40)
runtime.cc:582] native: #26 pc 001e67d9 /system/lib/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+236)
runtime.cc:582] native: #29 pc 00402594 /system/lib/libart.so (ExecuteMterpImpl+14612)
runtime.cc:582] native: #30 pc 000b4bf0 /dev/ashmem/dalvik-classes.dex extracted in memory from /data/app/cc.openframeworks.androidMultiOFActivitiesExample-Jl6A2NWxdhhztRx44kfvHg==/base.apk_21873_21873 (deleted) (cc.openframeworks.OFAndroidWindow.onDrawFrame+20)
runtime.cc:582] native: #31 pc 001c5a43 /system/lib/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEb.llvm.3434490817+378)
runtime.cc:582] native: #34 pc 003e44bb /system/lib/libart.so (MterpInvokeInterface+1010)
08-26 14:05:09.874 21873-21994/cc.openframeworks.androidMultiOFActivitiesExample A/tivitiesExampl: runtime.cc:582] native: #37 pc 001c5a43 /system/lib/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEb.llvm.3434490817+378)
runtime.cc:582] native: #42 pc 00c4e0ac /system/framework/boot-framework.vdex (android.opengl.GLSurfaceView$GLThread.run+48)
runtime.cc:582] native: #46 pc 00413cff /system/lib/libart.so (art_quick_to_interpreter_bridge+30)
runtime.cc:582] native: #53 pc 00074041 /system/lib/libc.so (__pthread_start(void*)+22)
runtime.cc:582] native: #54 pc 0001e47d /system/lib/libc.so (__start_thread+24)
runtime.cc:582] at cc.openframeworks.OFAndroidWindow.onDrawFrame(OFAndroidWindow.java:308)
runtime.cc:582] at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1571)
runtime.cc:582] at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)
runtime.cc:582]
runtime.cc:582]
08-26 14:05:09.874 21873-21994/cc.openframeworks.androidMultiOFActivitiesExample W/tivitiesExampl: 0xebadde09 skipped times: 0
08-26 14:05:09.875 21873-21994/cc.openframeworks.androidMultiOFActivitiesExample A/libc: Fatal signal 6 (SIGABRT), code -6 (SI_TKILL) in tid 21994 (GLThread 181), pid 21873 (tivitiesExample)

#3

Hi.

Where have you placed the Java function ?

It should be inside the follwing file, not in ofAndroid.java.
srcJava/cc/openframeworks/androidMultiOFActivitiesExample/OFActivityA.java

Hope this helps.
Greetings.

#4

Hi!
Already try in both sides and is crashing both.
I’m following this old post JNI questions: Java to C++ and C++ to Java strings problem

thanks

#5

did you try rebuilding everything ?

Hi! I was dealing with the same problem for the last two hours since I realized that ofAndroidLib needs to be Re-Builded in order to update the OFAndroid getStringToCppSide() method. After re-build everything worked well.

#6

Hi Zach,

Yes and still giving me the same error.

I think you are following the thread i post, not the code i post:

std::string ofApp::getJavaString() {
    jmethodID midCallBack = ofGetJNIEnv()->GetMethodID(ofGetJavaOFAndroid(), "getStringToCppSide", "()Ljava/lang/String;"); //"getStringToCppSide" is the name of a Java function of ofAndroid.java
    jstring resultJNIStr = (jstring)ofGetJNIEnv()->CallObjectMethod(ofGetJavaOFAndroid(), midCallBack);
    const char *resultCStr = ofGetJNIEnv()->GetStringUTFChars(resultJNIStr, NULL);
    std::string resultStr(resultCStr);
    ofGetJNIEnv()->ReleaseStringUTFChars(resultJNIStr, resultCStr);
    return resultStr;
}

in the OFAndroid.java:

private String getStringToCppSide() {
    return requiredstring;
}

This is woking. But is for send a String from java to OF

What i’m dealing with is this:
(send String from OF to java.
ofAndroid.java

public void setStringFromCppSide(String message) {

		Log.d("myTag", "This is my message");
	}

ofApp.h

  void sendStringtoJava(string message);

ofApp.cpp

void ofApp::update(){
sendStringtoJava("jala");
}
void ofApp::sendStringtoJava(std::string message) {
    jstring jStringParam = ofGetJNIEnv()->NewStringUTF(message.c_str());
    ofGetJNIEnv()->CallVoidMethod(ofGetOFActivityObject(), ofGetJNIEnv()->GetMethodID(ofGetJavaOFAndroid(), "setStringFromCppSide", "(Ljava/lang/String;)V"), jStringParam); //"setStringFromCppSide" is the name of a void of ofAndroid.java
    ofGetJNIEnv()->DeleteLocalRef(jStringParam);
}
#7

here’s an addon which seems to call a similar function to pass a string – maybe you can take a look at how they do it?

in particular they check if the function exists, maybe you can do that as well to see if there is some error. I don’t see anything obvious in the java or signature (typically I get JNI errors when I mess up the signature)

1 Like
#8

Thanks Zach,

Okay, i took a look the addon got the idea. I try to implement it in my .cpp but still can get it work, maybe adding the addon and modifying it would be easier.

#9

Hi Zach, @Rancs help me to solve it. Here is the right code if you need it or somebody else:

OFAndroid.java:

	public static void setStringFromCppSideStatic(String message) {
		Log.d("myTag", "This is my static message");
	}

ofApp.h:

    void sendStringtoJavaStatic(string message);

ofApp.cpp:

void ofApp::update(){
    sendStringtoJavaStatic("jala");
}

void ofApp::sendStringtoJavaStatic(std::string message) {
    jstring jStringParam = ofGetJNIEnv()->NewStringUTF(message.c_str());
    ofGetJNIEnv()->CallStaticVoidMethod(ofGetJavaOFAndroid(), ofGetJNIEnv()->GetStaticMethodID(ofGetJavaOFAndroid(), "setStringFromCppSideStatic", "(Ljava/lang/String;)V"), jStringParam);
    ofGetJNIEnv()->DeleteLocalRef(jStringParam);
}
2 Likes
#10

Hi @Drazinut,
Here is a the instance version if you need it :slight_smile:

cc/openframeworks/androidEmptyExample/OFActivity.java (or the example you use):

    public void setStringFromCppSide(String message) {
        Log.d("myTag", "This is my message");
    }

ofApp.h:

    void sendStringtoJava(string message);

ofApp.cpp:

void ofApp::update(){
    sendStringtoJava("jala");
}

void ofApp::sendStringtoJava(std::string message) {
    jstring jStringParam = ofGetJNIEnv()->NewStringUTF(message.c_str());
    ofGetJNIEnv()->CallVoidMethod(ofGetOFActivityObject(), ofGetJNIEnv()->GetMethodID(ofGetJNIEnv()->GetObjectClass(ofGetOFActivityObject()), "setStringFromCppSide", "(Ljava/lang/String;)V"), jStringParam); //"setStringFromCppSide" is the name of a void of ofAndroid.java
    ofGetJNIEnv()->DeleteLocalRef(jStringParam);
}
1 Like
#11

Hi @Ikkd ,

I just saw this, though it looks like you wrote it 8 days ago, I imagine when I posted a question on another topic where I was trying to get ofxMobileKeyboard to work in OF 0.10.1 and finding its way of connecting to JAVA was no longer supported?

In any case, thanks for the example of how to do that. I gave up and am instead making a software keyboard instead, but I will go back and try that out, as I would like to be able to get native keyboards and dialogs working in OF 0.10.1 Android and iOS apps eventually.

If/when I succeed at those tasks, I will share what I’ve got working.

#12

HI @Drazinut,

I been using android JNI in my OFandroid app.
Try the multipleOFactivities examples. You can write the JNI in activity and use also the layout to send the elements. And you can use the code above to get the dataflow from OF and JAVA. I been able to use keyboard, listview, buttons. You can use any JNI available.

#13

Thanks! I will try those examples out once I get through my current tasks.

I had a project (that may or may not rematerialize) where I was hoping to be able to use Auth0, which has a JAVA API - figuring this piece out might get me a step closer to that, too.