c++的.o文件的鏈接順序


linker對鏈接順序要求很嚴格,如果順序有誤,多半就會報undefined reference to xxxxxx的錯誤

文件目錄:

代碼:

main.cpp

1 #include "Test.h"
2 
3 using namespace std;
4 
5 int main()
6 {
7     Test::testLiftOff();
8     return 0;
9 }

 

Test.cpp

 1 #include "Test.h"
 2 
 3 #include "LiftOff.h"
 4 
 5 #include <zthread/Thread.h>
 6 
 7 #include <iostream>       // std::cout
 8 
 9 void Test::testLiftOff()
10 {
11     using namespace ZThread;
12 
13     try {
14         for (int i = 0; i < 5; ++i)
15         {
16             Thread th(new LiftOff(10, i));
17         }
18         std::cout << "waiting for lift off" << std::endl;
19     } catch (Synchronization_Exception &e) {
20         std::cerr << e.what() << std::endl;
21     }
22 }
23 
24 Test::Test()
25 {
26     //ctor
27 }
28 
29 Test::~Test()
30 {
31     //dtor
32 }

 

LiftOff.cpp

 1 #include "LiftOff.h"
 2 
 3 #include <iostream>
 4 
 5 using namespace std;
 6 
 7 LiftOff::LiftOff(int countDown_, int id_)
 8     :countDown(countDown_), id(id_)
 9 {
10     // do nothing
11 }
12 
13 LiftOff::~LiftOff()
14 {
15     cout << "LiftOff" << id << " destroyed" << endl;
16 }
17 
18 void LiftOff::run()
19 {
20     while (countDown--)
21         cout << id << " count: " << countDown << endl;
22     cout << id << "LiftOff!" << endl;
23 }

 

Test.h

 1 #ifndef TEST_H
 2 #define TEST_H
 3 
 4 
 5 class Test
 6 {
 7     public:
 8         static void testLiftOff();
 9 
10     private:
11         Test();
12         ~Test();
13 };
14 
15 #endif // TEST_H

 

LiftOff.h

 1 #ifndef LIFTOFF_H
 2 #define LIFTOFF_H
 3 
 4 #include <zthread/Runnable.h>
 5 
 6 class LiftOff : public ZThread::Runnable
 7 {
 8     public:
 9         LiftOff(int countDown_, int id_);
10         ~LiftOff();
11         void run();
12     private:
13         int countDown;
14         int id;
15 };
16 
17 #endif // LIFTOFF_H

顯然,main.cpp 通過 Test.h 引用 Test.cpp 的 implementation 。 說人話? 好吧 。。。 具體來說就是linker在發現main.cpp 中的 Test::testLiftOff() 調用的時候, 需要去找Test::testLiftOff()的implementation,去哪找?當然是Test.cpp中,編譯為obj文件后,其實就是main.o 依賴於 Test.o

我們把這種關系描述為 main.o < Test.o

類似的還有 Test.o < LiftOff.o  、 Test.o < zthread_win3.a

總的原則就是:如果A.o依賴於B.o,那么在linker命令中,A.o必須在B.o的左邊(可以不相鄰)

所以在鏈接的時候,命令為:

g++ -o test.exe main.o Test.o LiftOff.o -s zthread_win32.a // linker command 1

其實,只要順序不違反上面的關系定義,后面的順序是可以任意調整的,例如,實際上LiftOff.o與-s zthread_win3.a的順序調一下也是可以的

g++ -o test.exe main.o Test.o -s zthread_win32.a LiftOff.o // linker command 2

總結:

你編譯上面的代碼為:

g++ -c *.cpp

鏈接的時候上面給出的linker command 1、linker command 2任意選一個都行

 

另外:

事實上,在linux下,由於ZThread依賴於Posix Thread Library,在 -s zthread_xxx.a之后還需要-lpthread來加載Posix Thread Library,也是這個原因,見這篇隨筆


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM