Win32 API函数与它们的CRT对应函数(例如CopyMemory与memcpy)的区别

11
在编写Win32 C/C++代码时,使用Windows特定函数如lstrcpynCopyMemory是否有任何优势(例如性能?)与使用对应的CRT函数相比(除了CRT函数的可移植性之外)?
2个回答

11

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

您可以创建一个纯Win32应用程序,没有任何依赖关系,包括CRT(就像您可以使用NTDLL.DLL创建一个纯NT应用程序一样-我认为Windows的smss.exe是这样的进程)。即使如此,我认为对于大多数应用程序来说都无所谓。

更新 由于人们似乎对个别功能的差异非常着迷,尤其是memcpyCopyMemory,因此我想补充说明并非CRT中的所有函数都是Win32中的封装器。自然地,有些函数可以在没有Win32帮助的情况下实现(实际上,memcpy就是一个很好的例子),而其他函数则不能。除了可移植性之外,我认为性能不是使用CRT的最佳论据。

你应该选择最适合你的东西,通常这将是CRT。而且,在您认为合适的地方使用单个Win32函数(具有CRT等效函数)也没有任何问题。


1
需要注意的是,在使用memcpyCopyMemory的例子中,Windows SDK的头文件将CopyMemory定义为调用RtlCopyMemory的宏,而RtlCopyMemory又是调用memcpy的宏。 - Matthew
实际上,memcpymemmovememcmpstrlenmemset都是在ntdll.dll中实现的。因此CRT函数仍然是Win32函数的包装器,NtDll.dll函数的包装器,可以自行实现(例如格式化和数学),或者是入口点的一部分。例如,Rust除了数学和入口点之外,不使用MSVCRT做任何事情,甚至这也可能很快改变。 - alexchandel

3
这取决于函数和您的要求。
对于像memcpy这样的函数,选择Windows特定版本没有任何意义。保持简单和可移植,坚持使用标准C即可。
对于像mbstowcs这样的其他函数,您可能需要使用MultiByteToWideChar等其他功能,具体取决于您需要的功能。
个人来说,如果可能的话,我会选择C版本,只有在必要时才会选择Win32版本,因为没有理由编写特定于Windows的代码,而不是可移植的代码。

3
这里还有另一个很好的例子,即"memset",但你可能更喜欢使用"SecureZeroMemory",因为它不会被Windows编译器优化掉。 - Benj
3
@Mr_C64 - 当然,如果涉及到的内存位于栈上并且即将超出作用域,编译器可能会优化对memset的调用。这是可以的,但是如果数据是敏感的,比如密码,它将留在栈残留中,以后可能会被探测到。 - Benj
1
@CareyGregory:这不是一个错误,而是一个特性。 - user541686
1
@Mehrdad:我理解这么做的原因,但我仍认为,如果编译器错误地认为某个函数调用没有预期效果而消除它是非常不可取的。 - Carey Gregory
2
编译器并不会“错误地”相信任何东西;它的评估完全是正确的。所给的例子是关于敏感数据仍然留在堆栈上的问题。这不会影响程序的行为,而这正是编译器关心的。如果像这样的事情让你感到恐慌,你总是可以禁用优化。 - Cody Gray
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接