通过JNI将C ++字符串发送到Java [英] Send C++ string to Java via JNI

查看:111
本文介绍了通过JNI将C ++字符串发送到Java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建Android应用程序的项目的C ++方面.我需要一些信息(通过字符串和字符串数组)传递给Java应用程序(通过JNI).我以前从未做过,相反方向的人没有C ++的经验,并承认他们不能真正提供帮助.

I am working on the C++ side of a project that is building an Android application. There is some information (via strings and string arrays) that I need to pass to the Java application (via JNI). I have never done this before, and the people working in the reverse direction have no experience with C++ and admit that they cannot really help.

我确实找到了以下代码(来自这里)

I did find the following code (from here)

 #include <jni.h>  
    #include "ArrayHandler.h"  

    JNIEXPORT jobjectArray JNICALL Java_ArrayHandler_returnArray (JNIEnv *env, jobject jobj){        
      jobjectArray ret;  
      int i;  
      char *message[5]= {"first","second","third","fourth","fifth"};  
      ret= (jobjectArray)env->NewObjectArray(5,env->FindClass("java/lang/String"),env->NewStringUTF(""));  

      for(i=0;i<5;i++) {  
        env->SetObjectArrayElement(ret,i,env->NewStringUTF(message[i]));  
      }  
      return(ret);  
    }  

但这对我来说毫无意义.通常,我不确定如何将其合并到程序的C ++端,而且我无法确切了解其工作原理.代码是否在执行return(ret);行时发出消息?还是在for循环中执行该行?

But this makes no sense to me. Mostly, I am not sure how I am supposed to incorporate this into the C++ side of the program and I am failing to understand exactly how this works. Is the code sending out the message upon execution of the return(ret); line? Or during the execution of the line within for loop?

理想情况下,我希望将字符串/字符串数组实时"发送到行中,而不是在函数末尾发送,这样我就不必合并新函数.

Ideally, I would like the string/string array to be sent out "live" in line and not at the end of a function so that I do not have to incorporate a new function.

我发现的代码可以为我想要的代码工作(经过一些修改)吗?我正在寻找的东西甚至可能吗?如果是这样,我该怎么办?

Will the code I found work for what I want (with some adaptation)? Is what I am looking for even possible? If so, how can I do it?

编辑/更新: 花了整整一天的时间研究JNI和术语,我想我未能正确传达我在这里想要实现的目标以及对@jogabonito的回答/回复的评论.

EDIT/UPDATE: Having spent the day looking into JNI and the terminology, I think I have failed to correctly communicate what I am looking to achieve both here and as a comment to @jogabonito's answer/reply.

话虽如此.我正在处理的代码是针对IM客户端的,它将需要将消息和状态更新推送到Android Java应用程序(通过JNI),以便Android应用程序不会轮询更新.我设法学习了如何设置Java代码的函数来调用requrest信息.但是,我不知道如何在传入新消息或状态信息(Jabber节字符串)时将其推送到Java代码中.我在如何执行此操作时所见过的所有代码(例如,参见下文)似乎都需要从Java代码中获取信息(env,类,methodid等).

That being said. The code I am working on is for an IM client that will need to push message and presence updates to the Android java application (via JNI) so that the Android application does not poll for updates. I have managed to learn how to setup the functions for the java code to call to requrest information. However, I do not have any idea how to push new message or presence information (jabber stanza strings) to the java code when it comes in. All the code that I have seen on how to do this (see below for example) seems to require getting information from the java code (env, class, methodid, etc).

当不是调用该函数的java代码而是我的c ++代码时,对我来说这怎么可能是不可能的.任何解释/帮助将不胜感激.

It does not make sense to me how this is supposed to be possible when it is not the java code calling the function, but my c++ code. Any explanation/help would be very much appreciated.

#include <string.h>
#include <stdio.h>
#include <jni.h>

jstring Java_the_package_MainActivity_getJniString( JNIEnv* env, jobject obj){

    jstring jstr = (*env)->NewStringUTF(env, "This comes from jni.");
    jclass clazz = (*env)->FindClass(env, "com/inceptix/android/t3d/MainActivity");
    jmethodID messageMe = (*env)->GetMethodID(env, clazz, "messageMe", "(Ljava/lang/String;)Ljava/lang/String;");
    jobject result = (*env)->CallObjectMethod(env, obj, messageMe, jstr);

    const char* str = (*env)->GetStringUTFChars(env,(jstring) result, NULL); // should be released but what a heck, it's a tutorial :)
    printf("%s\n", str);

    return (*env)->NewStringUTF(env, str);
}

推荐答案

在共享的函数中,在c ++代码中,您将使用NewObjectArray创建对象数组.然后在for循环中,使用NewStringUTF创建一个字符串,然后使用SetObjectArrayElement将其存储在数组的索引中.直到现在,您的对象数组仅对您的c ++代码有效,而对您的java代码未知.只有当您返回它时,您的Java应用程序才能访问它.
我可以想到几种将字符串从c ++发送到java的方法,尽管它可能与您的意图不尽相同.

In the function you shared, in your c++ code you are creating an object array with NewObjectArray. Then in your for-loop you are creating a string with NewStringUTF and storing it at an index in your array using SetObjectArrayElement. Until now, your object array is only known to your c++ code and not to your java code. Only when you return it will your java app get access to it.
I can think of a couple of ways to send the string to java from c++, though it may not be exactly what you intended.

  1. 将String数组传递给您的本机函数.在本机代码中,您可以使用GetObjectArrayElement访问每个元素,并使用SetObjectArrayElement更新它.这可能毫无意义,因为您最终不得不调用一个我认为您不想要的函数.

  1. Pass a String array to your native function. In you native code you can access each element using GetObjectArrayElement and update it using SetObjectArrayElement. This will probably be pointless since you end up having to call a function which I persume you do not want.

如果您已经在Java代码中将字符串定义为字段,则可以使用GetFieldIDGetObjectField从本机访问该字符串,然后可以使用SetObjectField对其进行更新.我不知道您将如何向Java代码发出该字段已更新的信号(如果需要)

If you already have a string defined as a field in your java code, from your native get access to it using GetFieldID and GetObjectField, and you can update it using SetObjectField. I dont know how you will signal your java code that the field has been updated though ( if you need it)

编辑
您编写的更新函数应从java层调用.提示是函数Java_the_package_MainActivity_getJniString的名称.要从本机上下文中调用Java代码,您将需要引用Java中的envobj.看看如何加载我自己在Android上的C语言中的Java类?您可能还必须查找如何在JNI中使用全局引用

EDIT
The updated function which you have written is meant to be called from the java layer. The clue for this is name of the function Java_the_package_MainActivity_getJniString. To call java code from a native context, you will need references to the env and obj from java. Have a look at How do I load my own Java class in C on Android? for an approach to get this. You will also probably have to look up how to use global references in JNI

这篇关于通过JNI将C ++字符串发送到Java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆