gpt4 book ai didi

C++11 及更高版本 : shared_ptr for managing system resources provided by a low-level C library

转载 作者:搜寻专家 更新时间:2023-10-31 02:08:52 24 4
gpt4 key购买 nike

在过去的几年里,我主要是一名 C 开发人员,偶尔会编写一些 Python 代码。由于存在大量相互矛盾的来源,我正在努力找出在现代 C++ 中管理系统资源的正确方法。

我是 libgpiod 的作者- 一个通过字符设备控制 GPIO 的库(这是从用户空间管理 GPIO 的新方法,与现在已弃用的 sysfs 接口(interface)相反)。核心库代码是用 C 编写的,但我计划从 C++11 开始为其他语言提供绑定(bind)。

我不想详细介绍 GPIO 是什么,但一般来说,GPIO 线是一个可配置的引脚,我们可以控制它与 GPIO 芯片相关联,通常会暴露多条线。 C 库使用两个核心结构对这种两级层次结构进行建模:struct gpiod_chipstruct gpiod_line。两者都仅作为使用提供的 API 函数操作的不透明指针对用户可见。在内部,芯片与一个打开的文件描述符(位于 /dev/ 中的设备文件)和几个包含对象状态的变量相关联。

一个指向已分配芯片对象的指针从 gpiod_chip_open() 变体之一返回给用户。用户负责使用 gpiod_chip_close() 释放分配的资源。与大多数低级 C 代码一样,用户的任务是管理资源句柄。该库是明确的线程感知的(因为没有全局状态)但不是线程安全的。

芯片管理与其关联的所有线对象的资源,因此我下面的问题仅与芯片相关。

根据我目前所读的内容,在现代 C++ 中,通常不应手动使用 new 和 delete 运算符。因此,我对芯片类的最初想法是:

namespace gpiod {

class chip {

// [snip!]

private:

std::shared_ptr<::gpiod_chip> _m_chip;

};

}

这将使芯片类持有对 gpiod_chip 对象的引用。复制和移动构造函数和赋值运算符将简单地使用 shared_ptr 的引用计数来允许自由移动和复制芯片对象。当引用计数降为 0 时,自定义删除器将调用 C 对象上的 gpiod_chip_close()

但后来我注意到有些人建议在这种情况下使用工厂并让用户将对象包装在他们自己选择的智能指针中。

就现代 C++ 而言,对于我的用例的正确方法有什么建议吗?

最佳答案

没有必要使用 std::shared_ptr 除非您需要资源具有共享所有权,而在您的示例中似乎并非如此。大多数时候,只需要使用 std::unique_ptr 即可,它会在其构造函数中获取指针的所有权,然后在其析构函数中使用 delete 销毁该指针。你说你的库主要是用 C 实现的,所以 gpiod_chip_open() 返回的指针可能是用 malloc 分配的,所以用 delete 销毁它是未定义的行为。要解决此问题,您可以为 std::unique_ptr 指定一个自定义删除仿函数,它将调用 gpiod_chip_close() 其析构函数而不是 delete

你可以这样做:

#include <memory>

struct gpiod_chip_deleter {
void operator()(::gpiod_chip* chip) noexcept {
::gpiod_chip_close(chip);
}
};

using gpiod_chip_ptr = std::unique_ptr<::gpiod_chip, gpiod_chip_deleter>;

// ...

gpiod_chip_ptr chip(::gpiod_chip_open());

// ...

关于C++11 及更高版本 : shared_ptr for managing system resources provided by a low-level C library,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47001618/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com