我有一個接口,我希望能夠靜態鏈接模塊。例如,我希望能夠調用稱爲FOO的所有函數(儘管在單獨的文件中)或匹配某個原型,最終在文件中調用一個函數,而不在其他文件中創建頭文件。不要說這是不可能的,因爲我發現了一個黑客可以做到這一點,但我想要一個非黑客入侵的方法。 (黑客使用nm來獲取函數和原型,然後我可以動態調用函數)。另外,我知道你可以用動態鏈接來做到這一點,但是,我想靜態鏈接這些文件。有任何想法嗎?如何在C中創建模塊
回答
這在編寫測試代碼時有點常見。例如,您想調用以test_開頭的所有函數。因此,您有一個shell腳本,可以通過所有.C文件對grep進行操作,並提取與test _。*匹配的函數名稱。然後該腳本生成一個包含調用所有測試函數的函數的test.c文件。
例如,生成的程序看起來像:
int main() {
initTestCode();
testA();
testB();
testC();
}
另一種方式來做到這一點是使用一些技巧鏈接。這是Linux內核爲其初始化做的。作爲init代碼的函數用限定符__init標記。這在linux/init.h中定義如下:
#define __init __section(.init.text) __cold notrace
這會導致鏈接器將該函數放在.init.text節中。系統啓動後內核將從該部分回收內存。
爲了調用函數,每個模塊都會用一些其他的宏core_initcall(func),arch_initcall(func)等等(也在linux/init.h中定義)聲明一個initcall函數。這些宏將一個指向該函數的指針放入一個名爲.initcall的鏈接器部分。
在引導時,內核將「遍歷」.initcall節中的所有指針。通過走路看起來像這樣的代碼:
extern initcall_t __initcall_start[], __initcall_end[], __early_initcall_end[];
static void __init do_initcalls(void)
{
initcall_t *fn;
for (fn = __early_initcall_end; fn < __initcall_end; fn++)
do_one_initcall(*fn);
/* Make sure there is no pending stuff from the initcall sequence */
flush_scheduled_work();
}
符號__initcall_start,__initcall_end等得到鏈接腳本定義。
一般來說,Linux內核對GCC預處理器,編譯器和鏈接器都有一些最聰明的技巧。它一直是C技巧的一個很好的參考。
你真的需要靜態鏈接,並且同時在運行時選擇所有匹配的函數,對吧?因爲後者是動態鏈接的典型例子,我會說。
您確實需要一些機制來註冊可用的功能。動態鏈接將提供這一點。
把所有功能的表到每個翻譯單元:
struct functions MOD1FUNCS[]={
{"FOO", foo},
{"BAR", bar},
{0, 0}
};
然後把一張桌子到主程序中列出所有這些表:
struct functions* ALLFUNCS[]={
MOD1FUNCS,
MOD2FUNCS,
0
};
然後,在運行時,通過搜索表,並查找相應的函數指針。
我真的不認爲你可以做到這一點。 C並不完全具備後期約束力或者你似乎需要的那種內省。
雖然我不太瞭解你的問題。你想靜態鏈接時動態鏈接庫的功能嗎?因爲這對靜態鏈接沒有任何意義,所以您需要手頭已經有了二進制文件,這會使動態加載函數浪費時間,即使您可以輕鬆完成。
- 1. 在DNN中創建一個C#模塊
- 2. 如何在joomla中創建模塊2.5
- 3. 如何在spring中創建模塊
- 4. 如何在模塊中創建singelton值?
- 5. 如何在Magento中創建模塊
- 6. 如何在鈦中創建模塊?
- 7. 如何在asp.net中創建模塊?
- 8. 如何在Android Studio中創建模塊
- 9. 如何在C中的Lua模塊內創建一個Lua模塊?
- 10. 如何用C#在XNA中創建Tetris模塊?
- 11. 如何在C#中創建多門戶搜索模塊?
- 12. 如何在Angular2中爲多個模塊創建包裝模塊?
- 13. 如何創建JS模塊?
- 14. 如何創建子模塊?
- 15. 在C++模塊崩潰時創建PyTuple
- 16. 如何在joomla模塊內創建模塊
- 17. C/C++ - 如何在Apache HTTP Server中創建單例連接模塊?
- 18. 創建模塊
- 19. 如何創建C++模板?
- 20. 如何在drupal中爲skinr模塊創建模板文件?
- 21. 如何在Ant構建中創建模塊明智的jar?
- 22. 如何在Objective C中創建宏以在運行時執行多個模塊?
- 23. 在prestashop上創建模塊
- 24. 如何在C++創建模板類
- 25. 使用模塊模式在YUI3中創建自定義模塊
- 26. 創建可重用的cms模塊(C#)
- 27. python c api創建一個python模塊
- 28. 如何使用services模塊和soap_server模塊在drupal7中創建SOAP web服務?
- 29. Angular:如何使用其他模塊在模塊中創建的服務?
- 30. 如何創建一個pam模塊?
如果您想通過名稱在C中調用函數,您必須將該名稱聲明爲某個函數。這是頭文件的用途。你爲什麼不要他們? – TToni 2010-12-20 22:28:34
我看不出如何用'nm'推導出C函數的原型。爲了讓原型破碎,在那裏,你必須將文件編譯爲C++而不是C,否? – 2010-12-20 22:46:21
您通過爲函數名稱刷頭文件獲得原型(hacks,同意) – chacham15 2010-12-21 08:27:17