我可以用malloc和隐式cast替换对open_memstream的调用吗?
全部, 我有一个打印到流的程序。我需要在内存中缓冲这个流,然后根据需要将每一行打印到实际文件中 由于我可以用malloc和隐式cast替换对open_memstream的调用吗?,c,windows,stream,malloc,C,Windows,Stream,Malloc,全部, 我有一个打印到流的程序。我需要在内存中缓冲这个流,然后根据需要将每一行打印到实际文件中 由于fprintf()函数调用必须有一个文件*指针,所以我需要在内存中有指针寻址空间。我使用了open\u memstream()函数,但windows不支持此功能 由于malloc()返回一个void*指针,该指针可以根据需要神奇地强制转换到所需的指针,我可以将其用作我的文件*指针吗?如果是,有哪些注意事项?我需要注意空间不够吗 更新: 在找到open_memstream()的源代码后(这比应该的要
fprintf()
函数调用必须有一个文件*
指针,所以我需要在内存中有指针寻址空间。我使用了open\u memstream()
函数,但windows不支持此功能
由于malloc()
返回一个void*
指针,该指针可以根据需要神奇地强制转换到所需的指针,我可以将其用作我的文件*
指针吗?如果是,有哪些注意事项?我需要注意空间不够吗
更新:
在找到open_memstream()
的源代码后(这比应该的要难),看起来他们正在对malloc的空间进行文件流
既然是这样,而且我已经得到了它们的源代码,如果我不能得到一个工作版本来为windows与mingw交叉编译,我将使用se No.malloc()
只提供一块(可能未初始化)内存。没有“神奇”的演员阵容;当您执行int*buf=malloc(10*sizeof(int);
时,实际上是将buf
指向10个未初始化的整数
与文件对应的是FILE*f=malloc(10*sizeof(FILE));
它指向10个未初始化的文件结构,这没有任何意义。此外,如果幸运的话,写入未初始化的文件可能会导致崩溃
如果你告诉我们你的目标是什么平台以及你真正想要实现什么,那么帮助就更容易了。在POSIX上,你可以使用
shm_open()
获取指向“共享内存”和fdopen()的文件描述符
将文件描述符转换为文件*
。是的,它可能会耗尽空间。对于我之后的人,希望吧!有一个解决方案。正如我在问题中提到的,我使用的是windows不支持的open_memstream()
由于我有一个文件*
指针(不能更改为字符*
),我需要将其重定向到内存,直到稍后。由于我在内存中处理一个文件,我查看了mmap()
。它轻松地解决了问题,但同样,它只是linux
但是,windows包含了mmap()
的一个推论,称为MapViewOfFile()
。通过#ifdef
的魔力,我使用了任何必要的工具:
#ifdef WIN32
#include <windows.h>
#else
#include <sys/mman.h>
#endif
现在我有了更多的#ifdef
代码来确定需要使用哪个内存映射代码集。请注意这两个版本之间映射空间的差异。Windows映射16384字节和linux映射4096字节。这是因为较小的值会在Windows上出错,如中所述
当数据被发送到yyout
流时,会发生一系列的工作方法被调用。它用一个以null结尾的字符结束流,刷新它,然后倒带它。然后指向内存空间的指针通过一个函数指针,以及要打印到的正确流
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);
}
所有这一切的最终结果是,我有一个流到内存空间,就像open_memstream()
,还有一个char指针,如果需要,我可以用来遍历内存空间。它是跨平台的,而且(似乎)功能齐全
如果有人想了解更多详细信息或了解我应该解决的问题,请添加评论。你让它工作了吗?,很好!在研究同一问题时,我还发现了这个麻省理工学院授权的库,它看起来基本上做了相同的解决方案,尽管它试图跨平台,并检测用户环境提供了什么完成后,是否调用
UnmapViewOfFile
或除fclose
之外的任何其他清理功能?
#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
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;
}