如何通过JNI将java中的对象的地址赋值给c++指针变量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过JNI将java中的对象的地址赋值给c++指针变量相关的知识,希望对你有一定的参考价值。

如何通过JNI将java中的对象的地址赋值给c++指针变量如何通过JNI将java中的对象的地址赋值给c++指针变量
//java
JObject job=newJObject();

//c++
CObject *cob= ?//如何将job的内存地址赋值给cob

jni编程里, c端 只能操作部分数据类型. 比如 

    一般类型.int,char,float

    数组类型, 比如 int数组, float 数组.

    Buffer类型,比如 intbuffer

    String

而你希望的在c里 操作java类...那趁早别想了.人家就没这样的设计.

参考技术A http://wenku.baidu.com/view/34048f3069eae009581bec7a.html这可以参数

~
参考技术B

JNI - C++/Java 中的侦听器 - 是不是可以在 C++ 中实例化 Java 对象并将它们用作参数

【中文标题】JNI - C++/Java 中的侦听器 - 是不是可以在 C++ 中实例化 Java 对象并将它们用作参数【英文标题】:JNI - Listener in C++/Java - is it possible to instantiate Java objects in c++ and use them as parametersJNI - C++/Java 中的侦听器 - 是否可以在 C++ 中实例化 Java 对象并将它们用作参数 【发布时间】:2014-03-27 10:27:14 【问题描述】:

以下内容是否可用于 JNI?

public NativeClass 

    static 
        System.loadLibrary("dll");
    

    public static native void addListener(Listener listener);


public interface Listener 
    public void eventOccurred(Info info);


public Info 

    private final String s1;
    private final String s2;

    public Info(String s1, String s2);

    // ... getters for use in Java

可以吗

在 dll 上注册一个Listener 对象(据我发现应该没问题) 在c/c++代码中实例化一个Info对象,作为调用Listener.eventOccured(Info...)的参数?

或者什么是实现从 DLL 获取一些信息的侦听器的好方法?

在我的情况下 - 我们有一个 dll 可以做一些工作。我们从java调用这个dll。现在我们想为 dll 附加一个监听器,以便在工作时向我们推送一些进度信息。上面的例子是监听部分,不知道c/c++的构造函数调用Java构造函数是否可行。

在哪里可以找到描述答案的文档的提示会很好 - 我找不到回答我的问题的信息。

一小段代码,描述 c/c++ 部分将是锦上添花:)

【问题讨论】:

【参考方案1】:

简短的回答是肯定的,您可以通过 JNI 在本机层中保存、实例化和传递 Java 对象。

在 jni 文档中,您会找到可以为您执行此操作的函数。 http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html

您还将使用javap -sjavah 来帮助查找用于jni 的Java 方法签名并制作您的jni 标头。见http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javap.html & http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah.html

以下是您将要执行的操作的示例。我没有测试过它,所以只是将它用作编写自己的参考。注意:注意包符号(我假设没有包)和例外。任何 JNI 调用(env->...)都可能发生异常,因此请查看有关如何处理异常的文档(ExceptionCheckExceptionDescribeExceptionClear)。

JavaVM * savedVM = NULL;
JNIEXPORT void JNICALL Java_NativeClass_addListener(JNIEnv *env, jobject obj_instance, jobject listener_instance) 

   env->GetJavaVM( &savedVM );
   //save listener_instance for use later
   saved_listener_instance = listener_instance;


void doSomething()

    //Get current thread JNIEnv
    JNIEnv * ENV;
    int stat = savedVM->GetEnv((void **)&ENV, JNI_VERSION_1_6);
    if (stat == JNI_EDETACHED)  //We are on a different thread, attach
        savedVM->AttachCurrentThread((void **) &ENV, NULL);
    if( ENV == NULL )
        return;  //Cant attach to java, bail

    //Get the Listener class reference
    jclass listenerClassRef = ENV->GetObjectClass( saved_listener_instance );

    //Use Listener class reference to load the eventOccurred method
    jmethodID listenerEventOccured = ENV->GetMethodID( listenerClassRef, "eventOccurred", "(LInfo;)V" );

    //Get Info class reference
    jclass infoClsRef = ENV->FindClass( "Info" );

    //Create Info class
    jobject info_instance = ENV->NewObject( infoClsRef, ..... );//For you to fill in with your arguments

    //invoke listener eventOccurred
    ENV->CallVoidMethod( saved_listener_instance, listenerEventOccured, info_instance );

    //Cleanup
    ENV->DeleteLocalRef( info_instance );

【讨论】:

太好了,我找不到,或者是盲目地找到带有 ENV->NewObject(...) 的部分,以确保可以做我想做的事情。感谢您的完整回答!【参考方案2】:

这是一个很好的例子:https://github.com/NickZt/MyJNACallbackTest 此处详细解释了相同的代码: https://www.hackster.io/user2657268124/a-beginner-s-guide-to-implement-jni-callbacks-in-android-cd8226

【讨论】:

以上是关于如何通过JNI将java中的对象的地址赋值给c++指针变量的主要内容,如果未能解决你的问题,请参考以下文章

使用 JNI 将长值传递给 Java

JNI 通过多个 JNI 调用使 C++ 中的对象保持活动状态

如何把c++中的unsigned char* mData的数据指针通过jni把数据传给java使用?

通过 JNI (Cocos2dx) 获取 Java 对象到 C++

C++中内存分配问题

c++ 如何将一个vector内容赋值给另一个vector