gpt4 book ai didi

我可以用 malloc 和隐式转换替换对 open_memstream 的调用吗?

转载 作者:可可西里 更新时间:2023-11-01 13:25:30 25 4
gpt4 key购买 nike

全部,

我有一个打印到流的程序。我需要在内存中缓冲此流,然后根据需要将每一行打印到实际文件中。

因为 fprintf() 函数调用必须有一个 FILE * 指针,所以我需要在内存中指出指针寻址空间。我使用了 open_memstream() 函数,但 Windows 不支持它。

由于 malloc() 返回一个 void * 指针,该指针根据需要神奇地转换为必要的指针,我可以将其用作我的 FILE * 指针?如果是这样,有什么注意事项?我需要注意空间不足吗?

更新:

在找到 open_memstream() 的源代码之后,这比本来应该的要难,看起来他们正在对 malloc 空间执行文件流。

既然是这样,而且我已经得到了它们的源代码,我将考虑是否无法获得工作版本以使用 mingw 交叉编译 windows。

最佳答案

追随我的人,要有希望!有一个解决方案。如我的问题所述,我使用的是 open_memstream(),它在 Windows 上不受支持。

因为我有一个 File * 指针(这不能更改为 char *),所以我需要将它重定向到内存,直到稍后。由于我正在处理内存中的文件,因此我查看了 mmap()。它轻松解决了问题,但同样,它仅适用于 linux。

但是,Windows 包含一个 mmap() 的推论,称为 MapViewOfFile()。通过 #ifdef 的魔力,我使用任何必要的方法得到了它:

#ifdef WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#endif

稍后,在 main 方法中,我调用了两个平台都支持的 tmpfile()。这会为我打开一个保证唯一的临时文件的流。现在我有了 FILE * 指针,我需要 mmap() 空间。但是 mmap() 需要一个文件描述符,而不是一个流,所以我使用了 fileno() 函数来获取新的文件描述符。

/* create tmp file and get file descriptor */
int fd;
yyout = tmpfile();
fd = fileno(yyout);

现在我有更多的#ifdef 代码来确定需要使用哪个内存映射代码集。请注意两个版本之间映射空间的差异。 Windows 映射 16384 字节,linux 映射 4096 字节。这是因为较小的值会在 Windows 上出现段错误,如 my question here 中所述.

#ifdef WIN32
HANDLE fm;
HANDLE h = (HANDLE) _get_osfhandle (fd);

fm = CreateFileMapping(
h,
NULL,
PAGE_READWRITE|SEC_RESERVE,
0,
16384,
NULL);
if (fm == NULL) {
fprintf (stderr, "%s: Couldn't access memory space! %s\n", argv[0], strerror (GetLastError()));
exit(GetLastError());
}
bp = (char*)MapViewOfFile(
fm,
FILE_MAP_ALL_ACCESS,
0,
0,
0);
if (bp == NULL) {
fprintf (stderr, "%s: Couldn't fill memory space! %s\n", argv[0], strerror (GetLastError()));
exit(GetLastError());
}
#else
bp = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_FILE|MAP_PRIVATE, fd, 0);
if (bp == MAP_FAILED) {
fprintf (stderr, "%s: Couldn't access memory space! %s\n", argv[0], FileName, strerror (errno));
exit(errno);
}
#endif

现在有很多工作要做,其中数据被发送到 yyout 流。最终 flushData() 方法被调用。它使用一个空终止字符来完成流,刷新它,然后倒带它。然后指向内存空间的指针连同要打印到的正确流一起通过函数指针传递。

void flushData(void) {
/* write out data in the stream and reset */
while (currFields < headerFields) { fprintf(yyout, ",\"\""); currFields++; }
currFields = 0;
fprintf(yyout, "%c%c%c", 13, 10, '\0');
fflush(yyout);
rewind(yyout);
if (faqLine == 1) {
faqLine = 0; /* don't print faq's to the data file */
}
else {
(*printString)(outfile, bp);
fflush(outfile);
}
fflush(yyout);
rewind(yyout);
}

这是可以指向打印的功能之一。它遍历内存空间并打印每个字符,直到它遇到之前打印的空值。

int printAnsi( FILE *outstream, char *string) {
/* loop over the chars in string and print them to the outputstream as ansi */
char * ps = string;
while (*ps != '\0') {
fprintf(outstream, "%c", *ps);
ps++;
}
return 0;
}

所有这一切的最终结果是,我有一个内存空间流,就像 open_memstream() 一样,如果需要的话,我还可以使用一个 char 指针来遍历内存空间。它是跨平台的,并且(看起来)功能齐全。

如果有人需要更多详细信息或对我应该解决的问题有注释,请添加评论。

关于我可以用 malloc 和隐式转换替换对 open_memstream 的调用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10305095/

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