关于C编译器的内部逻辑

发布于 2024-09-09 08:38:21 字数 155 浏览 7 评论 0原文

当我们构建一个程序时,有些符号需要在链接时解析(例如.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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

久而酒知 2024-09-16 08:38:22

链接器完成这项工作。

  • 对于静态函数,链接器将库包含到可执行文件中。调用是针对内存中的固定位置的。
  • 对于动态库,链接器为库放置了一个运行时“搜索器”。动态库发布函数列表及其相对内存地址。因此,运行时可以填充指向它们的函数指针列表。

动态函数的原始代码可以编译为对函数指针的调用。
[事实上,这就是链接器的工作:替换对其引用的函数调用以生成可执行文件]。

The linker does the job.

  • For static functions, the linker include the libraries into your excutable. Calls are to fixed positions in memory.
  • For dynamic libraries, the linker put a runtime "searcher" for the library. Dynamic Libraries publish the list of functions and its relative memory addresses. So, the runtime can fill the list of function pointers to them.

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].

遥远的绿洲 2024-09-16 08:38:22

编译器需要在编译时知道函数声明。然后,链接器将在链接时链接到声明以使 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

不语却知心 2024-09-16 08:38:21

当您链接代码时,编译器会在静态库和动态库中搜索未定义的符号。如果它发现动态库导出的动态符号,那么它将符号解析推迟到运行时;如果它找到静态符号,它会立即解析该符号;如果它根本找不到该符号,则会报告错误(除非您正在编译共享库,在这种情况下就可以了)。

您可以使用 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.

︶葆Ⅱㄣ 2024-09-16 08:38:21

您必须为其主体在编译时不可用的函数声明一个原型

您可以通过包含适当的标头(.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.

飞烟轻若梦 2024-09-16 08:38:21

那些可以在链接时解决的问题是:然后在运行时在共享库中搜索那些不能的。

Those that can be resolved at link time are; those that can't are then searched for in shared libraries at run time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文