【问题标题】:C++ shared_ptr and Java native Object ownershipC++ shared_ptr 和 Java 本机对象所有权
【发布时间】:2014-10-15 05:39:21
【问题描述】:

在将 C++ 库中的功能公开给 Java 时,我最近遇到了一个关于 C++ shared_ptr 指针的问题。情况是对象本身以及与该对象相关的jlonghandle 都存在于 Java 部分中,但后续结构使用智能指针访问该对象。

我遇到的问题是:当智能指针被破坏或重置时,底层对象也会被删除。然而,Java 引用仍然指向该对象。

我尝试了很多,但我没有设法将所有权保留在 Java 端。是否有针对该问题的最佳做法或解决方案?

【问题讨论】:

    标签: java c++11 java-native-interface shared-ptr


    【解决方案1】:

    如果你想在 Java 保持引用对象的情况下保持对象,这里是有用的模式:

    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
    }
    

    另一方面,如果您担心 Java 引用可能会因为它超出本机对象的生命周期而变得无效,但不希望 Java 控制 MyObject 的释放,您可以使用 @987654323 做同样的技巧@。

    【讨论】:

    • 你是说reinterpret_cast 增加了shared_ptr 的引用计数吗?如果没有,这将不起作用,因为引用计数将在退出 Java_xxx_getNativeRef() 时降至零。
    • 请注意,我获得了一个指向共享指针的 GOP(旧指针)。这样,当它离开 get 的范围时,它仍然没有被销毁。
    • @AlexCohn 我一直在这样做:stackoverflow.com/a/5995770/6655884,直到你想到了简单地拥有一个共和党。明显更好:)
    • @AlexCohn 什么是清楚的? std::shared_ptr没有明确的方法?
    • 你又是对的。要记住我 5 年前的想法并不容易。从表面上看,这应该是delete *pSp
    【解决方案2】:

    shared_ptr 正是关于管理所有权。如果你想在 java 端管理所有权,我实际上不会使用 shared_ptr。

    作为一种技巧,您可以将 shared_ptr 与自定义删除器一起使用,这实际上删除了对象。

    【讨论】:

    • 这是真的,我完全同意,但是应该说我不能更改 c++ 代码,只能更改 Java 端。
    【解决方案3】:

    智能指针通常与分配/解除分配有关,shared_ptr 也不例外。如果您想要引用对象而不关心分配,请使用引用或指针。

    您不能为任务使用普通指针是否有特定原因?

    【讨论】:

    • 原因是我无法更改底层库。
    • 从 shared_from_this 继承将是一个很好的例子。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 2016-01-30
    • 1970-01-01
    相关资源
    最近更新 更多