简体   繁体   English

将 unique_ptr 与 GError 的自定义删除器一起使用

[英]using unique_ptr with custom deleter for GError

using unique_ptr with custom deleter for c functions that return a ptr is pretty straight forward, but how would i use it for functions that take ptr of ptr as parameter (like GError)使用带有自定义删除器的 unique_ptr 用于返回 ptr 的 c 函数非常简单,但是我如何将它用于将 ptr 的 ptr 作为参数的函数(如 GError)

I have faced this in couple of cases but but did not find a straightforward way to do this.我在几个案例中遇到过这种情况,但没有找到一种直接的方法来做到这一点。 am i missing something?我错过了什么吗?

using Element = std::unique_ptr<GstElement, void (*)(GstElement*)>;
using Error = std::unique_ptr<GError, void (*)(GError*)>;
...
GError* plain_err;
Element pipeline(gst_parse_launch(str, &plain_err), object_unref); // ok

Error uniq_err {nullptr, error_free};
Element pipeline(gst_parse_launch(str, &(uniq_err.get())), object_unref); // error: lvalue required as unary ‘&’ operand

The only way I could think of is by assigning it later我能想到的唯一方法是稍后分配

GError* plain_err;
Element pipeline(gst_parse_launch(str, &plain_err), object_unref);
Error uniq_err {plain_err, error_free};
plain_error = nullptr;

This part of your code:这部分代码:

GError* plain_err;
Element pipeline(gst_parse_launch(str, &plain_err), object_unref);

suggest that gst_parse_launch() allocates GError* and returns it.建议gst_parse_launch()分配GError*并返回它。 In this case, you cannot use unique_ptr your way.在这种情况下,您不能按照自己的方式使用unique_ptr Because unique_ptr just manages lifetime of a pointer.因为unique_ptr只管理指针的生命周期。

You can try something like this for managing your pointer using unique_ptr :您可以尝试这样的方法来使用unique_ptr管理您的指针:

struct ErrorRelease {
    void operator()(GError* ptr) {
        // release pointer
    }
};
using Error = std::unique_ptr<GError, ErrorRelease>;

GError* plain_err;
Element pipeline(gst_parse_launch(str, &plain_err), object_unref);

Error uniq_err(plain_err);

After this, you just must remember not to free plain_err manually because it is managed by your unique_ptr .在此之后,您必须记住不要手动释放plain_err ,因为它由您的unique_ptr管理。 It is OK to assign another value to it, just don't release it manually.可以给它分配另一个值,只是不要手动释放它。

I found returning a tuple from a lambda to be marginally better,我发现从 lambda 返回一个元组稍微好一点,

auto [pipeline, err] = [&]() noexcept {
    GError* err = nullptr;
    auto* pipeline = gst_parse_launch(str, &err);
    return std::tuple{Element{pipeline, object_unref}, Error{err, error_free}};
}();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM