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

所有,

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

由于fprintf()函数调用必须有一个FILE *指针,所以我需要在所指向的内存中寻址空间。 我曾经使用过open_memstream()函数,但在Windows上不支持。

由于malloc()返回一个void *指针,可以根据需要奇迹般地转换为必要的指针,我可以使用它作为我的FILE *指针吗? 如果是的话,那里有什么警告? 我需要注意空间不足吗?

更新:

在findopen_memstream()的源代码之后,它看起来好像在做一个文件stream到malloc的空间。

既然是这样,而且我已经得到了他们的源代码,那么如果我不能通过mingw得到一个工作版本来交叉编译windows的话。

对于那些追随我的人,有希望! 有一个解决方案。 正如我的问题所述,我正在使用open_memstream() ,这是不支持在Windows上。

由于我有一个File *指针(这不能改为char * ),我需要重定向到内存,直到以后。 由于我正在处理内存中的文件,所以我查看了mmap() 。 它轻松地解决了这个问题,但是,它只是Linux而已。

但是,windows包含一个名为MapViewOfFile() mmap()的推论。 通过#ifdef的魔法,我已经使用它的任何必要:

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

后来,在主要方法中,我调用了两个平台都支持的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); } 

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

 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() ,直到还有一个字符指针我可以用来走过内存空间,如果有必要。 它是跨平台的,并且(看起来)功能齐全。

如果有人想要更多的细节或者有关于我应该修复的问题,请添加评论。

malloc()只是给你一块(可能未初始化)的内存。 没有什么“神奇”的演员正在进行; 当你做int * buf = malloc(10*sizeof(int);你正在将buf指向10个未初始化的int。

FILE对应的东西是FILE * f = malloc(10*sizeof(FILE)); 在10个未初始化的FILE结构中指向f ,这没有任何意义。 而且,如果你幸运的话 ,写一个未初始化的文件很可能会导致崩溃。

如果你告诉我们你的目标是什么平台,以及你想达到什么样的目标,那么帮助会更容易。 在POSIX上,可以使用shm_open()获取指向“共享内存”的fdopen() ,使用fdopen()将文件描述符变为FILE* 。 是的,它可能会用完空间。

你需要的函数是sprintf()或相关的snprintf() ,它将把流格式化为一个字符串供以后使用。