Search code examples
javac++11java-native-interfaceshared-ptr

C++ shared_ptr and Java native Object ownership


While exposing functionalities from a C++ library to Java i recently faced a problem regarding C++ shared_ptr pointers. The case is that the Object itself as well as the jlonghandle related to that Object lives whithin the Java portion but subsequent structures access that Object using smart pointers.

The problem what i got is: When a smart pointer gets destroyed or reset the underlying object gets deleted as well. However the Java reference points still to that Object.

I tried a lot but i did not manage to keep ownership on the Java-Side. Are there any best practices or solutions to that problem ?


Solution

  • If you want to hold to the object as long as Java keeps reference to it, here is the useful pattern:

    jlong Java_xxx_getNativeRef(...)
    {
        std::shared_ptr<MyObject> *pNew = new std::shared_ptr<MyObject>;
        *pNew = whatever-you-do to obtain an std::shared_ptr<MyObject>;
        return reinterpret_cast<jlong>(pNew);
    }
    
    Java_xxx_releaseNativeRef(..., jlong nativeRef)
    {
        std::shared_ptr<MyObject> *pSp = reinterpret_cast<std::shared_ptr<MyObject> *>(nativeRef);
        delete *pSp;
        delete pSp; // thanks @LucasZanella
    }
    

    On the other hand, if you are concerned that the Java reference may become invalid because it outlives the lifecycle of the native object, but don't want Java to control release of MyObject, you can do the same trick with std::weak_ptr.