2017-10-09 219 views
1

我有一些問題需要理解下面的代碼如何工作。 我有三個文件鏈接到另一個共享對象的共享對象

Shared.c

#include "shared.h" 

void foo1 (void) { 
    printf("Test2"); 
} 

void foo2 (void) { 
    printf ("Test1"); 
} 

Shared.h

#include <stdio.h> 

extern void foo2 (void); 
extern void foo1 (void); 

Shared2.c

//#include "shared.h" 
#include "shared2.h" 


void shared2 (void){ 
    foo2(); 
} 

Shared2.h

#include <stdio.h> 
#include "shared.h" 

extern void shared2 (void); 

test.c的

#include <stdio.h> 
#include "shared2.h" 


int main (void){ 
    foo2(); 
} 

我想創建一個鏈接shared2.so取決於shared.so 上面的代碼不起作用二進制測試使用以下命令

gcc -c -Wall -Werror -fPIC -o shared.o shared.c 
gcc -shared -o libshared.so shared.o -lc 
gcc -c -Wall -Werror -fPIC -o shared2.o shared2.c 
gcc -shared -o libshared2.so shared2.o -lc 

由於此錯誤

shared2.c: In function ‘shared2’: 
shared2.c:7:2: warning: implicit declaration of function ‘foo2’; did you mean ‘feof’? [-Wimplicit-function-declaration] 
    foo2(); 
    ^~~~ 
    feof 

但是,上面的代碼工作,如果我刪除Shared2.c中的評論,我評論Shared2.h中的同一行。

  1. 爲什麼會出現此錯誤?

如果刪除了錯誤,我嘗試編譯test.c的

gcc -L/MyPath/ -Wall test.c -o test -lshared2 -lshared 

的編制工作只有當我libshared.so包括太多。

  1. 但是libshared.so不包含在libshared2.so中嗎?

編輯

您的建議我已經改變了文件,以這種方式

Shared.c

#include <stdio.h> 
#include "shared.h" 


void foo1 (void) { 
    printf("Test1"); 
} 

void foo2 (void) { 
    printf ("Test2"); 
} 

Shared.h

extern void foo1 (void); 
extern void foo2 (void); 

Shared2.c

#include "shared.h" 
#include "shared2.h" 


void shared2 (void){ 
    foo2(); 
} 

Shared2。ħ

extern void shared2 (void); 

並且使用下列命令

gcc -c -Wall -Werror -fPIC -o shared.o shared.c 
gcc -shared -o libshared.so shared.o -lc 
gcc -c -Wall -Werror -fPIC -o shared2.o shared2.c 
gcc -shared -o libshared2.so shared2.o -lc 

該代碼是沒有錯誤編譯。 相反,如果我做出Shared2.c以下更改Shared2.h

Shared2.c

#include "shared2.h" 

void shared2 (void){ 
     foo2(); 
    } 

Shared2.h

#include "shared.h" 

extern void shared2 (void); 

我獲得一個錯誤,我不明白爲什麼

shared2.c: In function ‘shared2’: 
shared2.c:7:2: error: implicit declaration of function ‘foo2’; did you mean ‘feof’? [-Werror=implicit-function-declaration] 
    foo2(); 
    ^~~~ 
    feof 

預處理輸出(在替換#include "shared.h"後)在兩種情況下都應該是相同還是不相同?爲什麼?

運動在我的測試中,libshared.solibshared2.so編譯後,我已經修改了我test.c的

test.c的

#include "shared2.h" 


int main (void){ 
    shared2(); 
} 

,如果我嘗試編譯與followng命令

gcc -L/MyPath/ -Wall -Werror test.c -o test -lshared2 

我獲得一個聯合國因爲gcc無法找到foo2(),在Shared2.c中調用。爲什麼這個錯誤?爲什麼它需要參考如果我使用共享對象?

+0

請注意,shared.h和shared2.h都不應包含'',因爲函數聲明不依賴於''中定義的任何類型。此外,「shared2.h」應該包含「shared.h」並不清楚。如果人們不能在範圍中調用'shared2()'而沒有'foo1()'和'foo2()'中的一個或兩個,那麼嵌套包含是合理的。如果人們可以在不知道或關心foo1()或foo2()的情況下調用shared2(),那麼不要嵌套包含。 –

回答

0
  1. 您可以通過在「shared2.c」中包含「shared.h」來消除此錯誤。
  2. libshared2.so不包括您在「測試」程序中使用的foo2函數的定義,這就是爲什麼您需要在編譯時添加libshared.so的原因。

你的「測試」程序實際上並沒有使用「libshared2.so」,只有foo2來自「libshared.so」。這裏你不需要-lshared2

+0

1.我做了什麼:我已經將「shared.h」包含在「shared2.c」中,它可以工作。我不知道爲什麼它不起作用,如果我試圖編譯上面張貼的代碼 – Bin

+0

2.你是對的,但是libshared.so是通過libshared2.so鏈接的:爲什麼我會在'測試期間寫'-lshared'。 c'文件編譯? – Bin

+0

1.那是因爲你在「shared2.c」中使用了'foo2',但是你沒有在任何地方聲明它。 「共享。h「包含該聲明。2.我沒有正確地閱讀這個問題 - 我會更新答案。 – aragaer