私の後に来る人たちのために、希望を持ってください!解決策があります。私の質問で述べたように、私は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
これで、使用する必要のあるメモリマッピングコードセットを決定するためのコードがもう少しあります。2つのバージョン間のマップされたスペースの違いに注意してください。Windowsマップ16384 bytes
とLinuxマップ4096 bytes
。これは、ここでの私の質問で述べたように、小さい値のsegfaultsが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()
メソッドが呼び出されます。ストリームを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);
}
これは、印刷のために指すことができる機能の1つです。メモリスペースをウォークし、前に印刷された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()
、必要に応じてメモリスペースをウォークスルーするために使用できるcharポインタもあります。それはクロスプラットフォームであり、(一見)完全に機能しています。
誰かが詳細を知りたい場合、または私が修正すべき問題についてのメモがある場合は、コメントを追加してください。