抛弃msvcrtXX库

时间:2023-03-09 13:33:09
抛弃msvcrtXX库

对于极致要求体积的程序来说。抛弃Msvcrt里的函数是必要的。(尤其是msvcrtXX库)因为要使用mscvrt中的函数,就需要带上相对来 说,不能容忍的几kb的,vcrt初始化函数,包围在我们的WinMain之外,而且对于高版本的msvcrtXX库,在开发某些程序的时候是不能臆想客 户机上就一定安装了对应的run time库了,要静态链接,又不知道大到哪里去了。抛弃mscvrt只是为了编译出来的程序体积小,可以说是针对特殊情况下的,不得已而为之,在不用考虑 体积的情况下,最好不要走这种极端。

抛弃Msvcrt说实话根本没有难度,只是很麻烦。

1.抛弃/GS

/GS是vc运行时库提供的。

如果没有设置,不启用/GS。可能会得到以下链接错误。

error LNK2001: 无法解析的外部符号 @__security_check_cookie@4

2.抛弃C运行时库的new、delete与malloc、free

替代的办法是用WinApi实现自己的版本(c运行时库其实就是对Heap系列的封装),或者直接使用WinApi Heap系列或者Virtual系列分配内存。

3.用ntdll中的RtlXXXMemory函数,替代C运行库提供的宏以及memXXX。

ntdll中导出了RtlMoveMemory、RtlCompareMemory、RtlFillMemory、RtlZeroMemory。完全足够使用。

我 现在的招数还是。。动态调用。。用GetModuleHandle和GetProcAddress,不过听说也能静态,我问了一下大神,大神说那种得用 wdk里提供的ntdll.lib,他不太放心。如果能有不链接这个lib就能静态调用的办法,那就太好了。我还没发现。

4.strXXXX系列wcsXXXX系列

有lstrXXXW/A系列替代或者StrStrX StrChrX等shlwapi。

还有StringCchXXXX和StringCbXXXX。

但是StringCchXXXX和StringCbXXXX属于提供源码的库(函数会被编译加入到我们的程序中),而不是动态链接的,使用这种库体积会比动态链接大一点。

Ps: 如果你完全不需要msvcrt库支持之后,一些什么平时很注意的。。用_beginthreadex代替CreateThread。。这种由于使用 msvcrt库才存在的编程准则。。不再有效。无须纠结。而且去除mscvrt本身就需要。不能调用_beginthreadex这种有msvcrt提供 的函数。

5.设置项目属性的链接器的输入选项。

忽略所有默认库。

将自己用到的库添加进去。

比如kernel32.lib user32.lib shlwapi.lib。

编译一下啊。看看还有什么需要调整的。

一般会看见

error LNK2001: 无法解析的外部符号XXXX

必然是这个函数属于msvcrt那套。需要替换成等价的API

或者你需要的库。你没有添加全。根据msdn里面写着的。调用某个函数需要的库lib添加上lib.

6.改入口点

我比较喜欢用预处理命令。

#pragma comment(linker, "/entry:wWinMain")

项目属性里也有设置。

7.说了这么多。。会有很多人说。。你麻烦不麻烦。你改这么多东西。。为什么不用汇编。。

首先。。我闲汇编麻烦。

其次。。用汇编一定小么?

再次。。你当编译器的性能优化是渣渣?

当然。绝对是有人能写出比编译器优化过的代码还好的汇编代码的,这点我相信。但是我觉得。这个人不是我,也大概不是还会把我这蛋疼文章看到末尾的你。