在 C 和 C++ 中,链接器如何找到具有已实现函数的正确文件?

Posted

技术标签:

【中文标题】在 C 和 C++ 中,链接器如何找到具有已实现函数的正确文件?【英文标题】:In C and C++, how does the linker find the right file with the implemented functions? 【发布时间】:2015-08-23 04:38:21 【问题描述】:

这是我用 C 编写的代码。我习惯于 Java,因此我不明白 C 编译器如何使用已实现的方法找到正确的源文件。

例如,如果我将 sample_c1.cpp 文件与 Main.cpp 放在一起,它将转到 sample_c1.cpp 的 on_start()。如果我删除 sample_c1.cpp 并将 sample_c2.cpp 与 Main.c 放在一起,它将转到 sample_c2.cpp 的 on_start()。

这是我的测试程序:

Main.c

//no includes to sample_c1.cpp or sample_c2.cpp

void on_start();
void on_stop();
int main(int argc, char* argv[])

    on_start();
    return 0;

sample_c1.cpp

//this is all i have in the file no class definition no nothing just implementations of the methods 
void on_start()
    ....


void on_stop()
    ......

sample_c2.cpp

//this is all i have in the file no class definition no nothing just implementations of the methods 
void on_start()
    ....


void on_stop()
    ......

【问题讨论】:

C 中没有“类”。 C 没有类,cpp 表示它是 C++。编程时了解您正在使用哪种语言编程非常重要。 @KenWhite 可能是C++,但是这段代码也是有效的C,答案是一样的。 @user63898 你是如何编译和链接你的程序的? 使用 VC++ 编译为 C++ 代码 (/TP) 【参考方案1】:

您的 IDE 会告诉编译器*您项目中所有源文件的名称。编译器* 一次处理它们。如果它发现您正在调用一个未在同一个源文件中定义的函数,那么它将在其他源文件中查找。如果您有一个名为sample_c1.cpp 的文件,那么它会在那里查找。如果您有一个名为sample_c2.cpp 的文件,那么它会在那里查找。如果您有一个名为 travel_back_in_time_and_murder_hitler.cpp 的文件,那么它会在那里查找。

真的没有什么令人兴奋的事情发生。 Java 中没有“类路径”。只是一堆制作程序的源文件。

 

* 实际上是链接器,但是编译器和链接器之间的区别超出了这个问题的范围。它基本上只是编译器的另一部分。

【讨论】:

这是我第一次看到这个,我做过 C++,但我总是必须包含标题 @user63898 标头包含原型。标题是手动重新输入(或复制粘贴)所有原型的替代方法。【参考方案2】:

一般来说,编译具有外部链接的符号的多个定义的程序会导致未定义的行为。

实际上,当你这样做时,链接器通常会抛出一个错误。

【讨论】:

@BillLynch 据我了解,提问者一次只使用其中一个文件。

以上是关于在 C 和 C++ 中,链接器如何找到具有已实现函数的正确文件?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 链接器错误 - 错误 LNK2005: ... 已定义

C++ 和 C 是不是使用相同类型的链接器?

C++ 的 AIX xlC 交叉编译/链接未找到 C 符号

如何将 C++ dll 静态链接到 .NET 库(将 c++ dll 构建到网络包装器 dll 以获取一个 dll)

混合 C 和 C++ 的库/链接器问题

C# 调用具有不同类型的相同扩展函​​数作为参数(可能是委托?)