【问题标题】:Win32 API functions vs. their CRT counterparts (e.g. CopyMemory vs. memcpy)Win32 API 函数与 CRT 对应函数(例如 CopyMemory 与 memcpy)
【发布时间】:2012-01-21 08:54:25
【问题描述】:

在编写 Win32 C/C++ 代码时,使用特定于 Windows 的函数(如 lstrcpyn 或 CopyMemory)代替相应的 CRT 函数(除了 CRT 函数的可移植性)是否有任何优势(例如性能?)?

【问题讨论】:

    标签: c++ c winapi


    【解决方案1】:

    至少有一些 CRT 函数在内部使用 Win32 函数。此外,CRT 需要额外的初始化(例如,strtok 等函数的线程特定数据)和清理,您可能不希望发生这种情况。

    你可以创建一个普通的 Win32 应用程序,而不依赖于包括 CRT 在内的任何其他东西(就像你可以使用 NTDLL.DLL 创建一个普通的 NT 应用程序 - 我认为 Windows 的 smss.exe 是这样的过程顺便说一句)。

    话虽如此,我认为这对于大多数应用程序来说并不重要。

    更新由于人们似乎对个别功能的差异如此着迷,特别是memcpy与CopyMemory,我想补充一点不是 CRT 中的所有功能都是 Win32 中的包装器。当然,有些可以在没有 Win32 帮助的情况下实现(实际上memcpy 是一个很好的例子),而另一些(明智地)不能。我相信@Merdad 在他的回答中暗示了一些东西。

    所以,撇开可移植性不谈,我不认为性能是或反对使用 CRT 的下一个最佳论据。 您应该选择最适合的,通常是 CRT。并且没有什么反对在您认为合适的地方使用单独的 Win32 函数(与 CRT 等效函数)。

    【讨论】:

    • 应该注意,作为使用memcpy 与CopyMemory 的示例,Windows SDK 标头将CopyMemory 定义为调用RtlCopyMemory 的宏,RtlCopyMemory 是调用@ 的宏987654331@.
    • 其实memcpy、memmove、memcmp、strlen、memset都是在ntdll.dll中实现的。因此,CRT 函数仍然是 Win32 函数的包装器、NtDll.dll 函数的包装器,可以自行实现(例如格式化和数学),或者是入口点的一部分。例如,Rust 不会将 MSVCRT 用于除数学和入口点之外的任何事情,甚至可能很快就会改变。
    【解决方案2】:

    这取决于功能和您的要求。

    对于memcpy 之类的东西,无论如何选择特定于 Windows 的版本没有任何意义。坚持使用标准 C 以保持简单和便携。

    对于mbstowcs 等其他内容,您可能需要改用MultiByteToWideChar 之类的内容,具体取决于您需要的功能。

    如果可能的话,我个人会选择 C ​​版本,之后只选择 Win32 版本——因为当它可以移植时,真的没有理由编写特定于 Windows 的代码。

    【讨论】:

    • memset 是另一个很好的例子,您可能更喜欢 SecureZeroMemory,因为它保证不会被 Windows 编译器优化掉。
    • @Mr_C64 - 当然,如果相关内存在堆栈上并且即将超出范围,编译器可能会优化对 memset 的调用。这很好,除了如果数据是敏感的,比如密码,它会留在堆栈残留中,以后可以探测。
    • @CareyGregory:这不是错误,而是一项功能。
    • @Mehrdad:我理解这样做的理由,但我仍然认为,因为编译器错误地认为它没有预期效果而消除函数调用是非常不可取的。
    • 编译器不会“错误地”相信任何东西;它的评估是完全正确的。给出的示例是关于堆栈中剩余的敏感数据。这不影响程序的行为,这是编译器所关心的。如果这样的事情吓到您,您可以随时禁用优化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多