Joh*_*osh 5 c linux windows io portability
我正在编写用作生成和输出 gif 图像的 cgi 的 C 程序。它们用在带有 form 标签的 HTML 页面中
<img src="/cgi-bin/gifprogram.cgi?param=val&etc">,其中查询字符串参数描述了由 cgi 生成的图像。
像这样调用的 C 程序 cgi 将它们的输出发送到 stdout。在这种情况下,输出是一个包含大量二进制(不可打印)字节的 gif 图像。这已经在 Unix/Linux 上运行良好。但是 Windows 显然需要一个单独的非便携式_setmode(_fileno(stdout),_O_BINARY)调用(和一些特定于 Windows 的调用#include)。否则,您会遇到常见的 cr/lf 问题,即每个 0x0A 前面都有一个虚假的 0x0D。这在 gif 中看起来不太好 :(
是否有任何可移植的方法来解决这个问题,使用 ANSI 标准 C 没有任何特定于平台的语法,并且没有很多#ifdef东西来尝试检测 Windows 编译环境?此外,一些 Windows 编译器显然使用,_setmode(_fileno(stdout),_O_BINARY)而其他编译器使用setmode(fileno(stdout),O_BINARY),我也必须尝试检测。
>>编辑<<回复评论...
谢谢你们。显然,我将不得不采用一些完全符合 posix 兼容/便携式的程序,并且只为 Windows [nb,JoNaThAn:真的,不需要编辑以大写:),--我的个人写作风格是故意的语法松散]。
下面是我正在考虑引入的一些愚蠢之处的第一次剪辑。据我所知,使用 mingw 似乎有效。它是否足够,即适用于所有或大多数其他编译器?是否有必要,即用更少/更易读的代码行来完成同样的事情的任何简短而整洁/快速和肮脏的方式?
/* ---
* windows-specific header info
* ---------------------------- */
#ifndef WINDOWS /* -DWINDOWS not supplied by user */
#if defined(_WINDOWS) || defined(_WIN32) || defined(WIN32) \
|| defined(DJGPP) /* try to recognize windows compilers */ \
|| defined(_USRDLL) /* must be WINDOWS if compiling for DLL */
#define WINDOWS /* signal windows */
#endif
#endif
#ifdef WINDOWS /* Windows opens stdout in char mode, and */
#include <fcntl.h> /* precedes every 0x0A with spurious 0x0D.*/
#include <io.h> /* So emitcache() issues a Win _setmode() */
/* call to put stdout in binary mode. */
#if defined(_O_BINARY) && !defined(O_BINARY) /* only have _O_BINARY */
#define O_BINARY _O_BINARY /* make O_BINARY available, etc... */
#define setmode _setmode
#define fileno _fileno
#endif
#if defined(_O_BINARY) || defined(O_BINARY) /* setmode() now available */
#define HAVE_SETMODE /* so we'll use setmode() */
#endif
#if defined(_MSC_VER) && defined(_DEBUG) /* MS VC++ in debug mode */
/* to show source file and line numbers where memory leaks occur... */
#define _CRTDBG_MAP_ALLOC /* ...include this debug macro */
#include <crtdbg.h> /* and this debug library */
#endif
#define ISWINDOWS 1
#else
#define ISWINDOWS 0
#endif
Run Code Online (Sandbox Code Playgroud)
以及确保stdout处于二进制模式的后续相应代码是
#if ISWINDOWS /* compiling for win... */
#ifdef HAVE_SETMODE /* try to use setmode()*/
if ( setmode ( fileno (stdout), O_BINARY) /* to set stdout */
== -1 ) /* handle error here*/ ; /* to binary mode */
#else /* setmode not available */
#if 1 /* so try this...*/
freopen ("CON", "wb", stdout); /* freopen stdout binary */
#else /* or maybe this... */
stdout = fdopen (STDOUT_FILENO, "wb"); /*fdopen stdout binary*/
#endif /* done */
#endif /* " */
#endif /* " */
Run Code Online (Sandbox Code Playgroud)
您会注意到我正在尝试建议 setmode() 替代方案。虽然我的替代测试没有成功,但我已经将语法留在原处以供将来参考,以防万一它最终被证明是有用的。
| 归档时间: |
|
| 查看次数: |
946 次 |
| 最近记录: |