1

As the title suggested i need some help creating JNI wrapper for this method

std::shared_ptr<xxx::FooInterface> createFooFactory() noexcept;

The error that i am getting is this

/Volumes/../../projects/xxx_fooFactory.cpp:34:19: error: reinterpret_cast from
      'std::__ndk1::shared_ptr<xxx::FooInterface>' to 'jlong' (aka 'long long') is not allowed
           return reinterpret_cast<jlong>(nativeObject);

I am not able to figure out what i am missing or doing wrong, All the related code are as follows, would be great if someone can provide feedback/advice as to what i might be missing. I must mention that this would be my first time writing jni wrapper. I have a class FooFactory.java

package xxx.FooFactory;

import PlatformInterface;

public class FooFactory extends PlatformInterface {
    protected FooFactory() {
    super();
    setNativeObject(nCreate());
    }

    @Override
    public void destroyNativeObject(long nativeObject) {
        destroyNativeObject(nativeObject);
    }

    private static native long nCreate();
    private static native void nDestroy(long nativeObject);
}

AutoGenerated jni header xxx_fooFactory.h

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class xxx_fooFactory */

#ifndef _Included_xxx_fooFactory
#define _Included_xxx_fooFactory
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     xxx_fooFactory
 * Method:    nCreate
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL Java_xxx_fooFactory_nCreate
  (JNIEnv *, jclass);

/*
 * Class:     xxx_fooFactory
 * Method:    nDestroy
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_xxx_fooFactory_nDestroy
  (JNIEnv *, jclass, jlong);

#ifdef __cplusplus
}
#endif
#endif

xxx_fooFactory.cpp

#include <jni.h>
#include "xxx_fooFactory.h"
....
#include <xxx/FooFactory.h>

using namespace xxx;
extern "C" {

/*
 * Class:     xxx_fooFactory
 * Method:    nCreate
 * Signature: ()J
 */
JNIEXPORT jlong JNICALL Java_xxx_fooFactory_nCreate
        (JNIEnv *env, jclass) {

    JAVA_BINDING_TRY{

           auto fooFactory = createFooFactory();
            if (fooFactory == nullptr) {
                throw JavaBindingException(JavaBindingException::kIllegalStateException, "Unable to create foo factory.");
            }

            auto nativeObject = std::shared_ptr<FooInterface>(fooFactory);
           return reinterpret_cast<jlong>(nativeObject);
    }
    JAVA_BINDING_CATCH(env);

    return 0;
}

/*
 * Class:     xxx_fooFactory
 * Method:    nDestroy
 * Signature: (J)V
 */
JNIEXPORT void JNICALL Java_xxx_fooFactory_nDestroy
(JNIEnv *env, jclass, jlong nativeObject) {
    JAVA_BINDING_TRY {
        if (nativeObject == 0) return;
        delete reinterpret_cast<std::shared_ptr<FooInterface>*>(nativeObject);
    } JAVA_BINDING_CATCH(env);
}

}
bourne
  • 1,083
  • 4
  • 14
  • 27
  • Well, to get the address of the `shared_ptr` you should use `&nativeObject`. But that doesn't seem like a good idea, because then you're returning the address of an object with automatic storage duration which is about to fall out of scope. The address that you return to Java should probably of something that you've allocated dynamically using `new`. So you may need to introduce another class that wraps the `shared_ptr` (if you actually need a `shared_ptr`). – Michael Dec 03 '21 at 12:25

0 Answers0