关于MSVC编译器,open(),_ open()和fopen()之间的区别? [英] Differenence among open(), _open(), and fopen() with regard to MSVC compiler?

查看:192
本文介绍了关于MSVC编译器,open(),_ open()和fopen()之间的区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到这三个功能都与打开文件有关.

I see these 3 functions are all related to opening a file.

打开:

不建议使用此POSIX函数.使用符合ISO C ++的_open 代替.

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

_open :

打开一个文件.不推荐使用这些功能,因为更安全 版本可用;参见_sopen_s,_wsopen_s.

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

打开:

打开一个文件.这些执行功能的安全性更高的版本 提供附加的参数验证和返回错误代码; 参见fopen_s,_wfopen_s.

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说POSIX版本的open已被弃用?并且是否有与下划线相关的命名约定,因此我可以根据其初次选择正确的功能?

So, why there are three of them? When to use which? I thought POSIX is good but why MSDN says the POSIX version of open is deprecated? And is there any naming convention related to the leading underscore so I can pick the right function based its first looking?

当我查看 ACPICA代码时,我看到以下代码: 看来_XXX版本可以禁用某些 MS语言扩展,这些扩展到底是什么?

And when I am looking into the ACPICA code, I see below code: It seems the _XXX version can disable some MS language extensions, what exactly are these extensions?

/*
 * 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

ADD 1

似乎单个下划线前缀_XXX是Microsoft的约定.例如 _DEBUG _ open . MSDN 的一些引用:

ADD 1

It seems the single underscore prefix _XXX is a Microsoft convention. Such as _DEBUG, _CrtSetDbgFlag, and the aforementioned _open. Some quote from the MSDN:

在Microsoft C ++中,带有两个下划线的标识符是 保留给编译器实现.因此,微软 约定是在Microsoft特定关键字之前加双 下划线.这些单词不能用作标识符名称.

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扩展.为了确保您的 程序是完全可移植的,您可以通过以下方式禁用Microsoft扩展 指定与ANSI兼容的/Za命令行选项(针对 ANSI兼容性).当您这样做时 Microsoft特定的关键字已禁用.

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.

启用Microsoft扩展程序后,您可以使用 程序中特定于Microsoft的关键字.为了符合ANSI, 这些关键字以双下划线开头.对于后退 兼容性,所有的单下划线版本 双引号关键字,除了__except,__ finally,__ leave和 支持__try.此外,__ cdecl可用,没有下划线.

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.

__ asm关键字替换了C ++ asm语法.预留给 与其他C ++实现的兼容性,但未实现.使用 __asm.

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

基于__的关键字在32位和64位目标上的使用受到限制

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

尽管根据上面的引用,__int64_int64都应该起作用,但是Visual Studio没有为_int64提供语法突出显示.但是_int64也可以编译.

Though according to above quote, __int64 and _int64 should both work, but Visual Studio provide NO syntax highlight for _int64. But _int64 can compile, too.

snprintf()和_snprintf()

推荐答案

  • 就Windows而言,打开文件的功能为

    • As far as Windows is concerned, the function for opening files is CreateFile. This returns a HANDLE and is provided by Kernel32.dll, not by Visual Studio. The HANDLE can be passed to other Windows API functions.

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

      The _open and open functions are POSIX compatibility functions to help you compile programs written for POSIX (Linux, macOS, BSD, Solaris, etc.) on Windows. These functions are defined by Visual Studio's C runtime, and presumably, they call CreateFile internally. The POSIX name of the function is open, but the function here is defined as _open in case you have already defined a function named open in your code. The function returns an int which can be passed to other POSIX functions. On Windows, this interface is a compatibility API provided by Visual Studio, but on Linux and macOS, this interface is the direct interface for the operating system, just like HANDLE on Windows.

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

      The fopen function is part of the C standard. It is defined by Visual Studio's C runtime, and presumably, calls CreateFile internally. It returns a FILE * which can be passed to other functions defined by the C standard.

      因此,总结一下这些选项:

      So, to summarize the options:

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

      • If you need to use the Windows API directly, like calling GetFileInformationByHandle or CreateFileMapping, you need a HANDLE and you should probably call CreateFile to open files.

      如果您已经为POSIX系统编写了程序,则可以使用open使其更容易将程序移植到Windows.如果您只为Windows编写,则使用此界面没有任何好处.

      If you have a program which is already written for POSIX systems, then you can use open to make it easier to port your program to Windows. If you are only writing for Windows, there are no advantages to using this interface.

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

      If your program only needs to do basic file operations like opening, reading, and writing, then fopen is sufficient and it will also work on other systems. A FILE * can be (and usually is) buffered by your application and supports convenient operations like fprintf, fscanf, and fgets. If you want to call fgets on a file returned by CreateFile or open you will have to write it yourself.

      可以将文件句柄从一种API转换为另一种,但是您必须注意所有权问题. 所有权"并不是一个真正的技术概念,它仅描述谁负责管理对象的状态,并且您要避免破坏不属于您的对象,并避免同一对象拥有多个所有者.

      It's possible to convert file handles from one API to the other, but you have to pay attention to ownership issues. "Ownership" is not really a technical concept, it just describes who is responsible for managing the state of an object, and you want to avoid destroying objects that you don't own, and avoid having multiple owners for the same object.

      • 对于Windows API,可以使用_open_osfhandle()HANDLE创建FILE *,并使用_get_osfhandle()FILE *获取HANDLE.但是,在两种情况下,该手柄都将由FILE *拥有.

      • For the Windows API, you can use _open_osfhandle() to create a FILE * from a HANDLE, and _get_osfhandle() to get the HANDLE from the FILE *. However, in both cases, the handle will be owned by the FILE *.

      对于POSIX API,可以使用fdopen()int文件描述符创建FILE *,还可以使用fileno()FILE *获取int文件描述符>.同样,在两种情况下,文件均由FILE *拥有.

      For the POSIX API, you can use fdopen() to create a FILE * from a int file descriptor, and you can use fileno() to get the int file descriptor from a FILE *. Again, in both cases the file is owned by the FILE *.

      请注意,Windows文件名是wchar_t的数组,而macOS/Linux/etc.文件名是char的数组,这一事实使可移植性变得复杂.

      Note that portability is complicated by the fact that Windows filenames are arrays of wchar_t, but macOS / Linux / etc. filenames are arrays of char.

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

      If you use a different C runtime like MinGW, or if you use the Windows Subsystem for Linux, things will be different.

      这篇关于关于MSVC编译器,open(),_ open()和fopen()之间的区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆