gpt4 book ai didi

visual-c++ - 关于 MSVC 编译器,open()、open() 和 fopen() 之间的区别?

转载 作者:行者123 更新时间:2023-12-02 00:44:18 29 4
gpt4 key购买 nike

我看到这 3 个函数都与打开文件有关。

open :

This POSIX function is deprecated. Use the ISO C++ conformant _open instead.

_open :

Opens a file. These functions are deprecated because more-secure versions are available; see _sopen_s, _wsopen_s.

fopen :

Opens a file. More-secure versions of these functions that perform additional parameter validation and return error codes are available; see fopen_s, _wfopen_s.

那么,为什么是三个呢?什么时候使用哪个?我认为 POSIX 很好,但为什么 MSDN 说 open 的 POSIX 版本已弃用?是否有任何与前导下划线相关的命名约定,以便我可以根据其第一眼选择正确的函数?

当我查看 ACPICA code 时,我看到下面的代码:_XXX版本似乎可以禁用一些MS语言扩展,这些扩展到底是什么?

/*
* Map low I/O functions for MS. This allows us to disable MS language
* extensions for maximum portability.
*/
#define open _open
#define read _read
#define write _write
#define close _close
#define stat _stat
#define fstat _fstat
#define mkdir _mkdir
#define snprintf _snprintf
#if _MSC_VER <= 1200 /* Versions below VC++ 6 */
#define vsnprintf _vsnprintf
#endif
#define O_RDONLY _O_RDONLY
#define O_BINARY _O_BINARY
#define O_CREAT _O_CREAT
#define O_WRONLY _O_WRONLY
#define O_TRUNC _O_TRUNC
#define S_IREAD _S_IREAD
#define S_IWRITE _S_IWRITE
#define S_IFDIR _S_IFDIR

加1

似乎单下划线前缀 _XXX 是 Microsoft 的惯例。如_DEBUG , _CrtSetDbgFlag ,以及前面提到的_open .一些引用自 MSDN :

In Microsoft C++, identifiers with two leading underscores are reserved for compiler implementations. Therefore, the Microsoft convention is to precede Microsoft-specific keywords with double underscores. These words cannot be used as identifier names.

Microsoft extensions are enabled by default. To ensure that your programs are fully portable, you can disable Microsoft extensions by specifying the ANSI-compatible /Za command-line option (compile for ANSI compatibility) during compilation. When you do this, Microsoft-specific keywords are disabled.

When Microsoft extensions are enabled, you can use the Microsoft-specific keywords in your programs. For ANSI compliance, these keywords are prefaced by a double underscore. For backward compatibility, single-underscore versions of all the double-underscored keywords except __except, __finally, __leave, and __try are supported. In addition, __cdecl is available with no leading underscore.

The __asm keyword replaces C++ asm syntax. asm is reserved for compatibility with other C++ implementations, but not implemented. Use __asm.

The __based keyword has limited uses for 32-bit and 64-bit target compilations.

虽然根据上面的引用,__int64_int64 应该都可以工作,但是 Visual Studio 没有为 _int64 提供语法高亮显示。但是 _int64 也可以编译。

添加 2

snprintf() and _snprintf()

最佳答案

  • 就Windows而言,打开文件的函数是CreateFile。 .这将返回一个 HANDLE 并且由 Kernel32.dll 提供,而不是由 Visual Studio 提供。 HANDLE 可以传递给其他 Windows API 函数。

  • _open and open函数是 POSIX 兼容函数,可帮助您在 Windows 上编译为 POSIX(Linux、macOS、BSD、Solaris 等)编写的程序。这些函数由 Visual Studio 的 C 运行时定义,并且大概在内部调用 CreateFile。该函数的 POSIX 名称是 open,但这里的函数定义为 _open,以防您已经在代码。该函数返回一个 int 可以传递给其他 POSIX 函数。在 Windows 上,该接口(interface)是 Visual Studio 提供的兼容 API,但在 Linux 和 macOS 上,该接口(interface)是操作系统的直接接口(interface),就像 Windows 上的 HANDLE 一样。

    <
  • fopen函数是 C 标准的一部分。它由 Visual Studio 的 C 运行时定义,并且大概在内部调用 CreateFile。它返回一个 FILE *,可以将其传递给 C 标准定义的其他函数。

因此,总结一下选项:

  • 如果您需要直接使用 Windows API,例如调用 GetFileInformationByHandleCreateFileMapping,您需要一个 HANDLE,并且您应该可能调用 CreateFile 来打开文件。

  • 如果您有一个已经为 POSIX 系统编写的程序,那么您可以使用 open 来更轻松地将您的程序移植到 Windows。如果您只是为 Windows 编写,那么使用此界面没有任何优势。

  • 如果您的程序只需要执行打开、读取和写入等基本文件操作,那么fopen 就足够了,它也可以在其他系统上运行。 FILE * 可以(通常是)由您的应用程序缓冲,并支持方便的操作,如 fprintffscanffgets。如果您想对 CreateFileopen 返回的文件调用 fgets,您必须自己编写。

可以将文件句柄从一个 API 转换为另一个 API,但您必须注意所有权问题。 “所有权”并不是一个真正的技术概念,它只是描述了谁负责管理一个对象的状态,你要避免销毁不属于你的对象,避免同一个对象有多个所有者。

  • 对于 Windows API,您可以使用 _open_osfhandle()HANDLE 创建一个 FILE *,并且 _get_osfhandle()FILE * 中获取 HANDLE。但是,在这两种情况下,句柄都属于 FILE *

  • 对于 POSIX API,您可以使用 fdopen()int 文件描述符创建一个 FILE *,并且您可以使用 fileno()FILE * 中获取 int 文件描述符。同样,在这两种情况下,文件都属于 FILE *

请注意,由于 Windows 文件名是 wchar_t 数组,而 macOS/Linux 等文件名是 char 数组,因此可移植性很复杂。

如果您使用不同的 C 运行时(如 MinGW),或者如果您使用适用于 Linux 的 Windows 子系统,情况就会有所不同。

关于visual-c++ - 关于 MSVC 编译器,open()、open() 和 fopen() 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44792526/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com