为函数设计接口时,强制用户(客户端)提供内存区域 >= 所需大小。怎么做,是好是坏?
Designing the interface for a function, force user(client) to provide memory region >= required size. How to, is it good or bad?
我正在设计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])
通过引用传递数组是一个好的解决方案吗?客户端可以分配内存并将其转换为数组并传递给函数。
你认为,在设计库的接口时,这种情况经常发生吗?你能提出我可以用作示例/基准的库吗?
有趣且重要的问题。
- 对于这样的设计,你能告诉我们什么,在这种设计中,客户端被迫分配给定的内存量,有什么建议吗
这是一种常见的情况,API需要指向客户端/用户分配的缓冲区的指针。但重要的是要确保,它也必须是分配缓冲区的代码才能解除分配
例如:库为客户端分配了一个缓冲区。它必须始终是应解除分配缓冲区的库,客户端不应尝试解除分配。这是因为库的编译可能与客户端不同,并且可能使用客户端的分配器可能不理解的不同分配器,从而导致堆损坏
当客户端将缓冲区传递到库时,情况相同,反之亦然。
- 如何强制客户端分配一定数量的内存
这就是我所用的:
#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也确保正确的类型,因此正确的缓冲区大小被传递给它
- EASTL矢量<向量<int>>连续的
- 将QGraphicsItem的移动区域限制在多边形区域内
- 有没有一种优雅而快速的方法来测试整数中的 1 位是否位于连续区域
- 在 Linux 中存储区域设置名称的缓冲区大小应该是多少?
- 两个连续的 OpenMP 并行区域会相互减慢速度
- 提升区域设置规范化带状字符,但不规范化重音
- 我的主窗口在创建时或单击更新区域时是否会收到编辑控件?
- 我可以将新的 std::tuple 放入内存映射区域,并在以后读回吗?
- 英特尔将指令存储在重叠的内存区域
- 如何给主窗口区域DKGRAY_BRUSH?
- 矢量擦除多个区域,2 x 擦除与单个分配?
- 错误:创建对象后无法分配区域
- 是否有任何区域设置会影响宽字符编码?
- GTKMM:拍摄绘图区域的屏幕截图?
- GTKMM:如何将键盘事件附加到绘图区域?
- 在 mmap'ed 区域上使用 memcpy 崩溃,for 循环不会
- 创建一个类来访问和指定向量类型,并构建一个获取位置并为其分配区域的类
- 当DPI感知,全屏和无框时,客户区域在WM_NCACTIVATE上擦除
- 提升获取文本的区域设置"Conversion failed"
- 用GTK创建逻辑门模拟器,如何制作放置区域