Вернуть объект C ++ в Java - PullRequest
8 голосов
/ 07 июня 2011

У меня есть пара функций JNI, которые должны работать с одним и тем же объектом c ++.Я хотел бы сохранить этот объект в объекте java, через который вызываются функции JNI, но, похоже, у Java нет способа хранить указатели для доступа к функциям позже.

Хорошо, я понимаю, что делаюужасная работа, объясняя себя, вот пример:

void clear_numbers(JNIEnv *env, jobject me) {
   me.myCppVector.clear();
}

void set_number(JNIEnv *env, jobject me, jint index, jint num) {
   me.myCppVector[index]=num;
}

jint get_number(JNIEnv *env, jobject me, jint index) {
   returnme.myCppVector[index];
}

Моя проблема заключается в создании jobject.myCppVector, чтобы я мог использовать его из различных вызовов функций.

Iнадеюсь, кто-то понимает мои разговоры

1 Ответ

6 голосов
/ 19 июня 2011

Я думаю, что стандартный способ сделать это - использовать long в java для хранения указателя, таким образом ваш java-код будет работать как в 32-битных, так и в 64-битных системах.Очевидно, вам нужно скомпилировать разные C ++ .so / .dll для каждой платформы.

Так что простая оболочка Java для класса C ++ с одним методом будет выглядеть примерно так:

class JavaClass
{
    private long native_ptr = 0;
    private native long createNativeInstance( params );
    private native String nativeMethod( params );
    private native void destroyNativeInstance( long p_native_ptr );
    public JavaClass( params )
    {
        this.native_ptr = createNativeInstance( params );
    }
    public String javaMethod( params )
    {
        nativeMethod( this.native_ptr, params );
    }
    public void finalize()
    {
        destroyNativeInstance( this.native_ptr );
    }
}

ИВаш код оболочки C ++ выглядит примерно так.(Я назвал класс C ++ CppClass)

JNIEXPORT jlong JNICALL Java_JavaClass_createNativeInstance
    ( JNIEnv*   p_jenv
    , jobject   p_jthis
    , params )
{
    // Convert params from Java types to C++ types if required
    return (jlong) new CppClass( converted_params );
}

JNIEXPORT void JNICALL Java_JavaClass_destroyNativeInstance
    ( JNIEnv*   p_jenv
    , jobject   p_jthis
    , jlong     p_native_ptr )
{
    if( p_native_ptr )
        delete (CppClass*)p_native_ptr;
}

JNIEXPORT jstring JNICALL Java_JavaClass_nativeMethod
    ( JNIEnv*   p_jenv
    , jobject   p_jthis
    , jlong     p_native_ptr
    , params
    )
{
    // Convert params from Java types to C++ types if required
    std::string cpp_result = ((CppClass*)p_native_ptr)->cppMethod( converted_params );
    jstring java_result = p_jenv->NewStringUTF( cppResult.c_str() );
    return java_result;
    // NOTE: std::string destructor will free cpp_result memory
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...