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