对于那些追随我的人,有希望!有一个解决方案。正如我的问题中所述,我使用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 bytes
和 linux 地图4096 bytes
。这是因为 Windows 上的较小值段错误,如我在此处的问题中所述。
#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 指针,我可以在必要时使用它来遍历内存空间。它是跨平台的,并且(看似)功能齐全。
如果有人想要更多详细信息或对我应该解决的问题有注释,请添加评论。