回答
您必須聲明原型的功能,其主體不可用編譯時間。
您可以通過包括適當的頭(.h
文件)將包含像這樣的定義,這樣做:
int foo(int bar);
注缺乏身體裏的。
通常與共享庫還有一個間接層,其中包含函數指針的結構形成。加載庫時,它會調整函數指針以引用共享庫中包含的函數。
當您鏈接您的代碼時,編譯器會在靜態庫和動態庫中搜索未定義的符號。如果它找到動態庫導出的動態符號,則將符號解析延遲到運行時;如果它找到一個靜態符號,它立即解析符號;如果它根本找不到符號,它會報告錯誤(除非您正在編譯共享庫,在這種情況下它可以)。
您可以使用nm -D
檢查由共享庫導出的動態符號。
鏈接器完成這項工作。
- 對於靜態函數,鏈接器將庫包含到您的可改變的字段中。通話是固定在記憶中的位置。
- 對於動態庫,鏈接器爲該庫放置一個運行時「搜索器」。動態庫發佈函數列表及其相關內存地址。所以,運行時可以填充它們的函數指針列表。
動態函數的原始代碼可以編譯爲對函數指針的調用。 [的確,這是鏈接器的工作:將函數調用替換爲生成可執行文件的引用]。
編譯器需要在編譯時知道函數聲明。鏈接器會在鏈接時鏈接到聲明以使其成爲可執行文件。
對於動態加載的庫,您可以插入代碼以在運行時使用dlopen dlsym和dlclose獲取符號。現在這些函數調用搜索這些符號,如果它們在動態庫中找不到,它們會返回錯誤。因此你也需要處理這個錯誤。動態庫加載不確保符號已被解析和鏈接。加載動態庫時,它仍然存在。
編輯:固定可怕的語法
因此,我們**在'c代碼'中通知**編譯器,而不是'編譯器選項'? – wamp 2010-07-15 04:20:24
@wamp - 我們使用編譯器選項鍊接庫。然而,在源代碼中,包含頭文件是爲了確保編譯器知道該符號。 – 2010-07-15 04:45:04
- 1. Tokenizing String C++編譯器/邏輯錯誤
- 2. C++對於開關邏輯
- 3. 從內部C/C++程序訪問GCC編譯器開關
- 4. 是依賴於C的零(!0)編譯器的邏輯否定嗎?
- 5. 將編譯器與編輯器關聯
- 6. c編程邏輯
- 7. 關於我的C語言編程邏輯等式
- 8. 關於Android的編譯器
- 9. 編輯器內部的行
- 10. 阻止基於模態控制器內部邏輯的AngularJS模態關閉
- 11. C編輯器或Windows CE編譯器
- 12. Objective-C編譯器和編輯器
- 13. Mono C#編譯器和MS C#編譯器關於作用域的區別
- 14. 關於編譯器和反編譯
- 15. 關於GUI與邏輯類
- 16. SCONS中用於C和C++編譯的編譯器開關的差異
- 17. ocaml編譯過程的邏輯
- 18. C++/DirectX'關卡編輯器'
- 19. C編程邏輯錯誤?
- 20. 關於變量範圍的C/C++編譯器優化
- 21. 關於ICC編譯的C++ 0x問題
- 22. 關於C編譯中的括號
- 23. 關於Visual C++中的編譯錯誤
- 24. 內部編譯錯誤C++的Cilk加
- 25. 可編程邏輯器件
- 26. Java:編譯內部相關類
- 27. 附加到表單如何工作? (SICP關於邏輯編程的部分)
- 28. 如何編輯位於自定義ASPX中的內容編輯器Web部件?
- 29. 我如何影響CMake的編譯器選擇邏輯?
- 30. 編譯器說邏輯,並且是未定義的標識符
我知道了'.h',卻怎麼也編譯知道'foo'應在鏈接時得到解決或運行只是基於該聲明的時間? – wamp 2010-07-15 02:04:58
@wamp:當你鏈接到一個動態庫,而不是自己編寫'dlopen'調用時,你會向鏈接器傳遞一個參數,告訴它哪些庫要搜索符號。例如,'-lpthread'會導致gcc鏈接到libpthread.so並允許使用'pthread_create'。 – Borealid 2010-07-15 02:49:44