![]() |
1
2
C运行时中的链接是围绕“main”函数的包装;它初始化运行C代码之前所需的所有内容。它不包含(m)任何“函数”,这些函数位于C标准库(动态链接)中。
我认为你误解了动态链接:它是由操作系统完成的。所以你告诉操作系统你的可执行文件需要DLL
有时,编译器在编译时包括(称为静态链接)一个库:它们这样做,这样操作系统就不必在运行时加载它,因此加载速度更快。
关于winapi:大多数对c库的调用都被转换成(一些)对winapi的调用;但是只有当它们必须与操作系统(I/O等)交互时。不同之处在于,在大多数平台上,C库是相等的,因此,如果您直接使用C库而不是Windows API,则可以提高可移植性。 更新 :
如果完全动态链接可执行文件,您询问了如何加载DLL?嗯:你不必!“加载dll”和“调用加载dll”之间的区别是,“加载dll”由操作系统在启动应用程序时完成。操作系统将在可执行文件中搜索特定的“导入表”。这是一张表,上面写着
真正地
需要,然后才能执行(即
“调用加载dll”也存在于
所以:您不必太担心在Windows上加载/卸载DLL。如果您有一个好的链接器,并告诉它动态链接库,那么一切都会很好地解决。 |
![]() |
2
3
按顺序回答问题:
维基百科误导了你。运行库并不总是链接的
在运行时
,而不是在您选择的情况下
静态地
链接运行时(
有一个
这里有两个API。一个是win32 api,它是Windows操作系统本身支持的函数列表。另一个API是由C编程语言标准定义的C运行时API。某些C运行时库函数(如打开和读取文件)最终将进行win32 api调用以执行实际的文件I/O。例如,其他C库函数
|
![]() |
3
1
在VisualC++和其他一些编译器中,CRT是为您连接的,除非您明确地告诉它不要(有时对于保持代码大小是有用的)。 在编译器选项中,您可以选择是拥有调试版本还是发布版本,以及它的“静态链接”还是“动态链接”。 静态链接将您直接调用的所有CRT函数中的所有实际代码放入您的EXE中。这对于减少所需的外部依赖关系非常有用-您只需运行exe,而不必担心是否安装了正确的XXXX.dll。缺点是,您提供的CRT函数可能存在问题(安全漏洞、崩溃、竞争条件),并且最终用户可以解决这些问题的唯一方法是生成新的exe。 动态链接将 参考 从exe调用的CRT函数。当您的exe加载并且您的代码调用引用的函数时,OS动态加载程序将看到该函数实际上位于msvcrt[d][version].dll中,然后加载该dll,查找该函数的地址,然后在代码中修正引用,以直接指向dll中的函数,这样下次,它的速度就像yo你会静态地连接它。显然,这里有一个初始启动延迟(与静态链接相比),但其优势是巨大的:系统dll被微软修补,所以你可以得到问题的更新(见上文),加载的dll是 共享 在内存中,因此,如果您引用的一个dll实际上已经被另一个进程使用,那么加载它所花费的时间就比另一个进程已经做了很多工作所花费的时间要短。 最后,是的,像printf()和scanf()这样的crt函数最终会与win32 api对话,但并不总是您认为的那样。使用Visual Studio/Windows SDK或SysInternals“ProcExp”中的“Depends”工具查看由任何特定进程拉入的dll及其使用的函数。 |
![]() |
MaPo · Linux,设置锁定ICMP_过滤器选项 4 月前 |
![]() |
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 4 月前 |
![]() |
Bobby · 复合字面值总是左值吗? 5 月前 |
![]() |
9-Pin · C: 嵌套结构的堆栈内存分配 5 月前 |