关于C编译器的内部逻辑
当我们构建一个程序时,有些符号需要在链接时解析(例如.lib
中的符号),
但有些符号可以在运行时解析(.dll),
我的疑问是编译器如何知道这一点,或者我们如何通知编译器这一点?
When we build a programe,some symbols are to be resolved at link time(like those in a .lib
),
but some can be resolved at run time(those in a .dll
),
my doubt is that how does the compiler know about this, or how do we notify the compiler about this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
链接器完成这项工作。
动态函数的原始代码可以编译为对函数指针的调用。
[事实上,这就是链接器的工作:替换对其引用的函数调用以生成可执行文件]。
The linker does the job.
The original code for dynamic functions could be compiled as a call to a function pointer.
[indeed, that's the job of the linker: replace the function calls to its references to produce the executable].
编译器需要在编译时知道函数声明。然后,链接器将在链接时链接到声明以使 aa 可执行。
对于动态加载的库,您可以插入代码以在运行时使用 dlopen dlsym 和 dlclose 获取符号。现在,这些函数调用会搜索符号,如果在动态库中找不到它们,则会返回错误。因此您也需要处理这个错误。动态库加载并不能确保符号已被解析和链接。加载动态库时它仍然必须存在。
编辑:修复了糟糕的语法
The compiler needs to know the function declaration at compile time. The linker will then link to the declaration at link time to make aa executable.
For dynamically loaded libraries you insert a code to fetch the symbols at runtime using dlopen dlsym and dlclose. Now these function calls search for the symbols and if they are not found in the dynamic libraries they return error. Hence you need to handle this error as well. A dynamic library loading doesnt ensure symbols have been be resolved and linked. It still has to be present when the dynamic library is loaded.
EDIT : Fixed terrible grammar
当您链接代码时,编译器会在静态库和动态库中搜索未定义的符号。如果它发现动态库导出的动态符号,那么它将符号解析推迟到运行时;如果它找到静态符号,它会立即解析该符号;如果它根本找不到该符号,则会报告错误(除非您正在编译共享库,在这种情况下就可以了)。
您可以使用 nm -D 检查共享库导出的动态符号。
When you link your code, the compiler searches both static and dynamic libraries for the undefined symbols. If it finds a dynamic symbol exported by a dynamic library, then it defers symbol resolution to runtime; if it finds a static symbol it resolves the symbol right away; and if it doesn't find the symbol at all, it reports an error (unless you're compiling a shared library, in which case it's OK).
You can examine the dynamic symbols exported by a shared library using
nm -D
.您必须为其主体在编译时不可用的函数声明一个原型。
您可以通过包含适当的标头(
.h
文件)来完成此操作,该标头将包含如下定义:int foo(int bar);
请注意,此处缺少主体。
通常,共享库还存在一个间接层,其中形成包含函数指针的结构。加载库时,它会调整函数指针以引用共享库中包含的函数。
You must declare a prototype for functions whose bodies are not available at compile time.
You do this by including the appropriate header (
.h
file) which will contain a definition like so:int foo(int bar);
Note the lack of a body there.
Often with shared libraries there is also a layer of indirection where a struct containing function pointers is formed. When the library is loaded, it adjusts the function pointers to reference the functions contained in the shared library.
那些可以在链接时解决的问题是:然后在运行时在共享库中搜索那些不能的。
Those that can be resolved at link time are; those that can't are then searched for in shared libraries at run time.