在堆上存储unique_ptr的最简单方法是什么?

Arc*_*hie 0 c++ unique-ptr

Java很久,第一次使用C++.

我正在编写一个包装现有C++ API的Java类,看起来像这样:

public class Foo implements Closeable {

    private long handle;

    public Foo(File file) {
        this.handle = Foo.openFile(file.toString());
    }

    // other methods go here...

    public void close() {
        Foo.closeFile(this.handle);
        this.handle = 0;
    }

    private static native long openFile(String file);
    private static native void closeFile(long handle);
}
Run Code Online (Sandbox Code Playgroud)

我们将指向本机C++对象的指针填充到handle字段中.

问题是C++库没有给我一个指针,它给了我一个unique_ptr<Foo>.所以这必须被移到堆上openFile()(因此它不会超出范围),然后被销毁closeFile().

我无法让这个工作,我不确定我是否正确地做到了.在C++中正确执行此操作的最简单/最简洁的方法是什么?

这是我目前正在做的事情:

// This holds a unique_ptr<T>, typically on the heap, until no longer needed
template <class T>
class PointerHolder {
public:
    PointerHolder(unique_ptr<T> ptr) {
        this->ptr = std::move(ptr);
    }
    T * get() const {
        return this->ptr.get();
    }
private:
    unique_ptr<T> ptr;
};

// Holder for a Foo
typedef PointerHolder<Foo> FooHolder;

jlong JNICALL
Java_Foo_openFile(JNIEnv *jenv, jclass jcls, jstring file)
{
    ...

    // Get smart pointer to native object from provided C++ library
    unique_ptr<Foo> ptr = ...

    // Save pointer on the heap until closeFile() is invoked sometime later
    const FooHolder *const holder = new FooHolder(std::move(ptr));

    // Return pointer encoded as a Java long
    return reinterpret_cast<jlong>(holder);
}

void JNICALL
Java_Foo_closeFile(JNIEnv *jenv, jclass jcls, jlong handle)
{
    // Delete pointer holder, and by extension, storage object
    delete reinterpret_cast<FooHolder *>(handle);        // CRASH HERE
}
Run Code Online (Sandbox Code Playgroud)

它是否正确?如果是这样,可以简化吗?

在任何情况下,现在程序都崩溃了closeFile(),但我不知道它是否崩溃,因为我做错了或者我正在使用的库中有一些错误(它相对较新且有错误).

感谢任何"指针".

Ben*_*igt 5

它可以简化.

既然你必须与Java的生命周期管理集成,那么对unique_ptr你没有任何好处.你也可以T直接管理对象的生命周期,而不是它的包装器(当然也不是FooHolder包装器的unique_ptr包装器T- 这太多包装).

只要打电话release()unique_ptr<T>得到T*一个需要delete,当你用它做-d.