为函数设计接口时,强制用户(客户端)提供内存区域 >= 所需大小。怎么做,是好是坏?

Designing the interface for a function, force user(client) to provide memory region >= required size. How to, is it good or bad?

本文关键字:gt 区域 接口 函数 用户 内存 客户端      更新时间:2023-10-16

我正在设计DLL接口,当我试图为具有以下功能的函数提供接口时,出现了问题:
它接受char* inputData对其进行编码,结果是较大大小的char* outPutdata数据,它将其返回(使用返回语句或作为函数中的附加参数&)给用户
我选择资源模型,客户端管理资源(分配、释放),Dll使用它们。

输入/输出数据的S大小是已知的并且是固定的。为了使我的库正常工作,我需要客户端为inputData和outPutdata分配至少所需数量的字节。

问题由两部分组成:
1。你能告诉客户这样的设计吗分配给定的内存量,有什么建议吗
2。如何强制客户端分配一定数量的内存?

对于第1部分:我没有找到任何资源,所以欢迎链接
关于第2部分:我考虑以下功能:

bool/*isOK*/encode(uint8_t(&inData)[SOME_CONSTANT],uint8_t(&outData)[ANOTHER_CONSTANT])

通过引用传递数组是一个好的解决方案吗?客户端可以分配内存并将其转换为数组并传递给函数。

你认为,在设计库的接口时,这种情况经常发生吗?你能提出我可以用作示例/基准的库吗?

有趣且重要的问题。

  1. 对于这样的设计,你能告诉我们什么,在这种设计中,客户端被迫分配给定的内存量,有什么建议吗

这是一种常见的情况,API需要指向客户端/用户分配的缓冲区的指针。但重要的是要确保,它也必须是分配缓冲区的代码才能解除分配
例如:库为客户端分配了一个缓冲区。它必须始终是应解除分配缓冲区的库,客户端不应尝试解除分配。这是因为库的编译可能与客户端不同,并且可能使用客户端的分配器可能不理解的不同分配器,从而导致堆损坏
当客户端将缓冲区传递到库时,情况相同,反之亦然。

  1. 如何强制客户端分配一定数量的内存

这就是我所用的:

#include <iostream>
#include <memory>
#include <type_traits>

static const size_t INPUT_ALLOC_SIZE = 1024;
static const size_t OUTPUT_ALLOC_SIZE = 1024 * 10;
template <size_t Size, typename Allocator>
struct Deletor {
void operator()(typename Allocator::pointer ptr) {
Allocator a;
a.deallocate(ptr, Size);
}
};
template <size_t Size, typename Allocator = std::allocator<char>>
struct AllocWrapper
{
friend AllocWrapper<INPUT_ALLOC_SIZE> allocate_input_buffer();
friend AllocWrapper<OUTPUT_ALLOC_SIZE> allocate_output_buffer();
AllocWrapper(AllocWrapper&& other): buffer_(std::move(other.buffer_)) {}
private:
AllocWrapper() {
Allocator a;
buffer_.reset(a.allocate(Size));
}
std::unique_ptr<typename Allocator::value_type[], Deletor<Size, Allocator>> buffer_ = nullptr;
};

AllocWrapper<INPUT_ALLOC_SIZE> allocate_input_buffer()
{
return AllocWrapper<INPUT_ALLOC_SIZE>();
}
AllocWrapper<OUTPUT_ALLOC_SIZE> allocate_output_buffer()
{
return AllocWrapper<OUTPUT_ALLOC_SIZE>();
}
template <size_t InSize, size_t OutSize, typename Allocator,
typename = typename std::enable_if<(InSize == INPUT_ALLOC_SIZE) ||
(OutSize == OUTPUT_ALLOC_SIZE)>::type>
bool encode(AllocWrapper<InSize, Allocator>& input,
AllocWrapper<OutSize, Allocator>& output)
{
return false;
}

int main() {
auto i_buf = allocate_input_buffer();
auto o_buf = allocate_output_buffer();
encode(i_buf, o_buf);
return 0;
}

注意:这绝不是为了生产目的而编写代码的方式,但这肯定是朝着正确方向迈出的一两步。缓冲区的分配或释放以及需要如何完成完全由客户端控制,而且API也确保正确的类型,因此正确的缓冲区大小被传递给它