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);
}
我们会将指向本机 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
}
这个对吗?如果可以,是否可以简化?
无论如何,现在程序正在崩溃closeFile()
,但我无法判断它是否正在崩溃,因为我做错了什么或者我正在使用的库中有一些错误(它相对较新且有错误)。
感谢任何“指针”。
解决方案
它可以简化。
由于您必须与 Java 的生命周期管理集成,这对unique_ptr
您没有任何好处。您还不如直接管理对象的生命周期T
,而不是它的包装器(当然也不是FooHolder
包装器的unique_ptr
包装器T
- 包装太多了)。
当你完成它时,只需调用release()
它unique_ptr<T>
来获得一个T*
需要-d 的东西。delete
推荐阅读
- c# - 是否可以使用git标记所有文件
- azure - 如何将 .yml 作业脚本作为单个任务,作为具有其他步骤的管道的一部分?
- php - 没有这样的元素:无法找到元素:{"method":"css selector","selector":"body select[name='Accept']"}
- doctrine - mysql 函数的本机查询或 DoctrineExtensions
- azure - 由于资源提供程序注册错误,无法创建 Azure Web App Bot
- android - ERROR: Could not find org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.31
- php - 通过 WooCommerce 中的功能显示高级自定义字段
- php - 播种/创建多对多关系
- excel - export-csv powershell后格式化excel文件
- javascript - Node JS - 通过它们的键合并对象,其中键是未知的