是否有(跨平台)方法从 C++ std::fstream 获取 C FILE* 句柄?
我问的原因是因为我的 C++ 库接受 fstreams 并且在一个特定的函数中我想使用一个接受 FILE* 的 C 库。
原文由 Bek 发布,翻译遵循 CC BY-SA 4.0 许可协议
在 Linux 中执行此操作的另一种方法:
#include <stdio.h>
#include <cassert>
template<class STREAM>
struct STDIOAdapter
{
static FILE* yield(STREAM* stream)
{
assert(stream != NULL);
static cookie_io_functions_t Cookies =
{
.read = NULL,
.write = cookieWrite,
.seek = NULL,
.close = cookieClose
};
return fopencookie(stream, "w", Cookies);
}
ssize_t static cookieWrite(void* cookie,
const char* buf,
size_t size)
{
if(cookie == NULL)
return -1;
STREAM* writer = static_cast <STREAM*>(cookie);
writer->write(buf, size);
return size;
}
int static cookieClose(void* cookie)
{
return EOF;
}
}; // STDIOAdapter
用法,例如:
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/iostreams/device/file.hpp>
using namespace boost::iostreams;
int main()
{
filtering_ostream out;
out.push(boost::iostreams::bzip2_compressor());
out.push(file_sink("my_file.txt"));
FILE* fp = STDIOAdapter<filtering_ostream>::yield(&out);
assert(fp > 0);
fputs("Was up, Man", fp);
fflush (fp);
fclose(fp);
return 1;
}
原文由 Jettatura 发布,翻译遵循 CC BY-SA 3.0 许可协议
3 回答2k 阅读✓ 已解决
2 回答3.9k 阅读✓ 已解决
2 回答3.2k 阅读✓ 已解决
1 回答3.2k 阅读✓ 已解决
1 回答2.7k 阅读✓ 已解决
3 回答3.4k 阅读
1 回答1.6k 阅读✓ 已解决
最简洁的答案是不。
原因是
std::fstream
不需要使用FILE*
作为其实现的一部分。因此,即使您设法从std::fstream
对象中提取文件描述符并手动构建一个 FILE 对象,您也会遇到其他问题,因为您现在将有两个缓冲对象写入同一个文件描述符。真正的问题是为什么要将
std::fstream
对象转换为FILE*
?虽然我不推荐,但您可以尝试查找
funopen()
。不幸的是,这 不是 POSIX API(它是 BSD 扩展),因此它的可移植性存在问题。这也可能是为什么我找不到任何人用这样的对象包裹
std::stream
的原因。这允许您构建一个
FILE
对象并指定一些将用于执行实际工作的函数。如果您编写适当的函数,您可以让它们从实际打开文件的std::fstream
对象中读取。