2017-09-21 103 views
-1

海蘭,我有以下結構:即F2採用F1解決在靜態庫「未定義的參考」一個重定向

lib1.a 
     U f1 
00000000 T f2 
lib2.a 
00000000 T f3 


main.c: 
    #define f1(a, b) f3(a, b) 
    int main(){ 
    f2(a, b); 
    } 

注意。

有沒有一種方法可以編譯這個解決'未定義的引用'而無需修改代碼或庫?

主要問題不是爲什麼我得到'未定義的引用'爲f1(因爲它是未定義的,顯而易見),但我如何編譯這個沒有執行f1。一些類似於映射的東西,我想在編譯完成類似於重定向之後被稱爲f3而不是f1(這就是爲什麼在main.c中定義集合)。

感謝

====編輯==: 好了,所以,由於這樣的事實,這個問題太難理解,我會添加來源:

lib2.c - - > $ gcc -c lib2.c; AR RCS lib2.a lib2.o

#include <stdio.h> 
#include <stdlib.h> 

int f3(int c, char *d) 
{ 
    printf("Rly: %d %s \n", c,d); 
    return 1; 
} 

lib2.h

int f3(int c, char *d); 

lib.c - > $ GCC -c lib.c; AR RCS lib.a lib.o

#include <stdio.h> 
#include <stdlib.h> 

int f2(int c, char *d) 
{ 
    printf("%d %s\n", c,d); 
    f1(c,d); 
    return 1; 
} 

lib.h

int f2(int c, char *d); 

的main.c - > $ GCC的main.c lib.a lib2.a

#include <stdio.h> 
#include <stdlib.h> 

#include "lib.h" 
#include "lib2.h" 

#define f1(a, b) f3(a, b) 

int main(int argc, char **argv) 
{ 
    f2(argc, argv[0]); 
    return 
} 

這是我爲創建類似場景而創建的文件。 無法修改lib.a和lib2.a。只有main.c和我如何編譯它們。

+1

的【什麼是未定義參考/解析的外部符號錯誤可能的複製以及如何修復它?(https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – Olaf

+0

這不是一個編譯器錯誤。 – Olaf

+0

@Olaf謝謝你的回答。我會盡力記住那篇文章。但這裏的問題不是爲什麼我有「未定義的參考」,但如果有一種方法與LIB1和LIB2編譯它,因爲它是隻與main.c中的變化,如果需要的。請注意,main.c必須調用f2,我希望f2調用f3而不是f1。 – dFroze

回答

0

你不能用宏來完成這種「重定向」(#define)。

要理解爲什麼不呢,記得宏擴展只是簡單的文本替換它由預處理器(cpp)來完成 - 運行前的文件交給編譯器(cc1),它實際產生的彙編代碼第一遍。特別是,當您在main.c中定義一個宏時,它只會在main.c的預處理過程中看到,因此它必須發生的任何影響必須發生在那裏。宏有時可以用來代替函數,但它們是完全不同的動物。

因此,在您的程序中,如果在main.c的任何位置使用標識符f1,則預處理器會將其替換爲f3。但事實並非如此,所以這個宏並沒有任何效果,並且cc1從來不知道它甚至不存在,連接器ld也不知道。如果你可以在lib.c中定義宏,它會做你想做的事,但你說你不能那樣做。

實現你想要的最簡單和最便攜的方法是在main.c(或任何其他源文件,也許是一個新文件)中實際定義f1作爲全局函數。

int f1(int c, char *d) 
{ 
    return f3(c, d); 
} 

它也可以告訴的是,在目標代碼f1任何引用應被解析爲f3鏈接器來實現的,但它是不可移植。如果您的系統使用GNU ld連接,然後

gcc -Wl,--defsym=f1=f3 main.c lib.a lib2.a 

會做到這一點。但是我建議,只有作爲最後的手段,如果由於某種原因,簡單的方法是完全不合適的。


注意,這隻會工作,如果你的f1有完全相同的原型(參數,的參數類型,返回類型)作爲呼叫f1lib.c期待。目前您的lib.c應該產生一個警告(隨時注意警告!!!!!),因爲你叫f1沒有範圍的聲明。在現實中lib.c應該有一個像int f1(int, char*);聲明呼叫之前的某個地方出現。 (如果你離開它,你就會得到一個「隱式聲明」,但你不能信任它永遠是正確的。)

+0

謝謝,很好的解釋了:)「--defsym」似乎什麼,我一直在尋找最佳的解決方案。 – dFroze