在 libc 中,有一个用于实现自定义
FILE*
流的扩展机制,它允许将自定义打开/读取/查找/关闭回调附加到自定义结构。
我在自定义流和 cookie 实现上找到的一些文档:
我正在寻找一个底漆来扩展
fmemopen(...)
行为,以便在流创建时传递的缓冲区将在 fclose(...)
处释放,但以重用现有 fmemopen
功能的方式扩展它,并希望以可移植的方式尊重地做不同的 libc。是否可以?怎样做才能做到这一点?
在某种程度上,我的问题是是否可以从
fmemopen
返回的不透明结构/指针“继承”并使用 close
缓冲区指针的版本“覆盖”/“包装” free()
回调通过了。
谢谢!
UPD: 目前,我通过跟踪数组中
FILE*
生成的所有指针 fmemopen
并保留分配的缓冲区的相应引用来实现此功能。然后我有一个自定义的关闭函数,它会遍历这个数组并释放 sidekick 缓冲区。但看来这个libc cookie机制可以让这个更加优雅。
是否可以以“便携式”方式(glibc/musl libc)从
fmemopen
生成的FILE*
中收回缓冲区指针?
我正在寻找一个底漆来扩展
行为,以便在流创建时传递的缓冲区将在fmemopen(...)
处释放,但以重用现有fclose(...)
功能的方式扩展它,并希望以可移植的方式尊重地做不同的 libc。可以吗?fmemopen
如果您让 POSIX
fmemopen()
为您分配缓冲区(通过传递空指针作为第一个参数),那么该缓冲区将在 fclose()
自动释放。 无需延期。 当然,这仅当您打开流进行更新时才有用,因为取出您写入的数据的唯一方法是重新定位流并通过 I/O 函数读回数据。
如果您希望让流接管您提供给它的预分配缓冲区的管理,那么我的第一个建议就是不要这样做。 以这种方式模糊分配内存的管理是很糟糕的形式。 如果您计划在流关闭之前丢失指向缓冲区的指针,那么让
fmemopen()
从头到尾管理缓冲区,如前所述。 如果您不计划在流的生命周期内丢失缓冲区指针,那么您根本不应该尝试将释放自动附加到文件关闭。 显式解除分配。 如果您觉得有必要,请编写一个处理闭包和释放的函数。 我保证这会消除你以后的悲伤。
如果您仍然坚持实现具有您所描述的内存管理行为的自定义流,那么 MUSL 似乎已经采用了 GNU 的
fopencookie()
扩展,因此您应该能够将其与 Glibc 和 MUSL 一起使用(请验证)。 我不知道其他 C 标准库实现中是否可以使用它。 您可以通过这种方式包装 fmemopen()
提供的流,但是您不能 extend 直接使用或调用与 fmemopen()
提供的流关联的四个 I/O 函数。