对于那些在我之后查看的人,请放心!有一个解决方案。如我问题中所述,我正在使用
open_memstream()
,但这在Windows上不受支持。
由于我有一个
File *
指针(无法更改为
char *
),我需要将其重定向到内存中,直到稍后再处理。既然我要处理内存中的文件,我研究了
mmap()
。它很方便地解决了问题,但只适用于Linux。
不过,Windows包含与
mmap()
相对应的东西,称为
MapViewOfFile()
。通过神奇的
#ifdef
,我已经让它使用必需的内容:
#ifdef WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#endif
接下来,在主方法中,我调用tmpfile()
函数,在两个平台上都支持。这将为我打开一个流到保证唯一的临时文件。现在,我有了FILE *
指针,需要使用mmap()
映射空间。但是mmap()
需要一个文件描述符而不是流,所以我使用fileno()
函数获取新的文件描述符。
int fd;
yyout = tmpfile();
fd = fileno(yyout);
现在我有一些更多的#ifdef
代码,用于确定需要使用哪个内存映射代码集。请注意两个版本之间映射空间的差异。Windows将映射16384字节
,而Linux将映射4096字节
。这是因为较小的值在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) {
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;
}
else {
(*printString)(outfile, bp);
fflush(outfile);
}
fflush(yyout);
rewind(yyout);
}
这是一个用于打印的函数之一。它遍历内存空间并打印每个字符,直到遇到之前打印的null字符。
int printAnsi( FILE *outstream, char *string) {
char * ps = string;
while (*ps != '\0') {
fprintf(outstream, "%c", *ps);
ps++;
}
return 0;
}
所有这一切的最终结果是我有了一个类似于
open_memstream()
的流到内存空间的东西,同时也有一个字符指针可以在必要时遍历内存空间。它是跨平台的,并且(看起来)完全可用。
如果有任何人想要更多细节或者有关问题需要我修复的注释,请添加评论。