gpt4 book ai didi

c - 使用 C++11 智能指针作为 C 函数参数

转载 作者:行者123 更新时间:2023-12-01 22:51:33 24 4
gpt4 key购买 nike

虽然这应该是一个微不足道的问题,但到目前为止我还找不到答案。在 C API 中,有许多函数将指针和指向指针的指针作为参数。如何正确使用智能指针作为 C API 的参数。

这是一个我想转换为使用 std::unique_ptr 的示例:

FMOD_SYSTEM* system = nullptr;
result = FMOD_System_Create(&system); // Create the main system object

FMOD_SOUND* musicStream;
result = FMOD_System_CreateSound(system,
musicStreamPath,
FMOD_CREATESTREAM,
nullptr,
&musicStream);

引用: FMOD_System_Create FMOD_System_CreateSound

我开始将智能指针声明为:

std::unique_ptr<FMOD_SYSTEM> system = nullptr;
std::unique_ptr<FMOD_SOUND> musicStream = nullptr;

如果我使用 .get(),这里是编译器错误:

cannot convert 'std::unique_ptr::pointer {aka FMOD_SOUND*}' to 'FMOD_SOUND**' for argument '5' to 'FMOD_RESULT FMOD_System_CreateSound(FMOD_SYSTEM*, const char*, FMOD_MODE, FMOD_CREATESOUNDEXINFO*, FMOD_SOUND**)' musicStream.get());

                                                   ^

最佳答案

您的问题是因为 C API 希望您将 指针的地址传递给 FMOD_SYSTEM,以便 API 可以用结果填充该指针— 即,它将 FMOD_SYSTEM* 作为输出参数

在 C++ 中,惯用的方法是将一个引用传递给一个(智能?)指向 FMOD_SYSTEM 的指针,即 C API 所在的位置

FMOD_RESULT FMOD_System_Create(FMOD_SYSTEM **system);

FMOD_SYSTEM *system;
result = FMOD_System_Create(&system);

C++ API 是

FMOD_RESULT FMOD_System_Create(std::unique_ptr<FMOD_SYSTEM> &system);

std::unique_ptr<FMOD_SYSTEM> system;
result = FMOD_System_Create(system);

但是,这个 C++ API 有一个大问题!问题是创建 FMOD_SYSTEM将它包装在unique_ptr 中是不同的问题,不应该像这样混在一起。例如,如果我正在用线程做一些聪明的事情并且真的需要我的 FMOD_SYSTEMshared_ptr 而不是简单的 unique_ptr 管理怎么办?我必须创建一个 unique_ptr 以作为输出参数传递,然后 std::move 将其放入 shared_ptr 之后?这既丑陋又(微观)低效。

std::unique_ptr<FMOD_SYSTEM> fake_system;
result = FMOD_System_Create(fake_system);
std::shared_ptr<FMOD_SYSTEM> system(std::move(fake_system));

答案是要认识到问题的根源在于参数本身,而解决方案是值语义。我们想要编写的惯用 C++ 语法是

auto system = std::make_unique<fmod_system>();

我们获得该语法的方法是将 C API 的原始指针包装在值类中:

class fmod_system {
FMOD_SYSTEM *ptr;
fmod_system() {
auto result = FMOD_System_Create(&ptr);
if (result != FMOD_OK) {
ptr = nullptr;
throw something;
}
}
fmod_system(fmod_system&&) = default;
fmod_system& operator=(fmod_system&&) = default;
fmod_system(const fmod_system&) = delete;
fmod_system& operator=(const fmod_system&) = delete;
~fmod_system() {
auto result = FMOD_System_Release(ptr);
assert(result == FMOD_OK); // destructors shouldn't throw: use your best judgment here
}
};

事实上,此时我们的调用者可以放弃 unique_ptr 混淆并简单地写

fmod_system system;

除非出于某种原因他们真的需要额外的指针语义层。

关于c - 使用 C++11 智能指针作为 C 函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27680981/

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