當加載共享庫通過函數dlopen()
打開時,有沒有辦法讓它在主程序中調用函數?加載的庫函數如何在主應用程序中調用符號?
回答
代碼(的lib):與
gcc -shared -olibdlo.so dlo.c
#include <stdio.h>
// function is defined in main program
void callb(void);
void test(void) {
printf("here, in lib\n");
callb();
}
編譯
這裏的主程序代碼(從dlopen手冊頁複製並調整):
#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
void callb(void) {
printf("here, i'm back\n");
}
int
main(int argc, char **argv)
{
void *handle;
void (*test)(void);
char *error;
handle = dlopen("libdlo.so", RTLD_LAZY);
if (!handle) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror(); /* Clear any existing error */
*(void **) (&test) = dlsym(handle, "test");
if ((error = dlerror()) != NULL) {
fprintf(stderr, "%s\n", error);
exit(EXIT_FAILURE);
}
(*test)();
dlclose(handle);
exit(EXIT_SUCCESS);
}
使用Build
gcc -ldl -rdynamic main.c
輸出:
[[email protected] dlopen]$ LD_LIBRARY_PATH=. ./a.out
here, in lib
here, i'm back
[[email protected] dlopen]$
的-rdynamic
選項把在動態符號表中的所有碼元(其被映射到存儲器中),不僅使用的符號的名稱。詳細瞭解它here。當然,你也可以提供函數指針(或者函數指針的結構)來定義庫和主程序之間的接口。這實際上是我可能選擇的方法。我從其他人那裏聽說,在Windows中做-rdynamic
並不是那麼容易,它也會使庫和主程序之間的通信變得更清晰(你可以精確地控制可以調用的內容而不是),但它也需要更多的管家。
是的,如果您爲庫提供了一個指向該函數的指針,我相信該庫將能夠在主程序中運行/執行該函數。
下面是一個例子,並沒有編譯它所以要小心)dlo.c的
/* in main app */
/* define your function */
int do_it(char arg1, char arg2);
int do_it(char arg1, char arg2){
/* do it! */
return 1;
}
/* some where else in main app (init maybe?) provide the pointer */
LIB_set_do_it(&do_it);
/** END MAIN CODE ***/
/* in LIBRARY */
int (*LIB_do_it_ptr)(char, char) = NULL;
void LIB_set_do_it(int (*do_it_ptr)(char, char)){
LIB_do_it_ptr = do_it_ptr;
}
int LIB_do_it(){
char arg1, arg2;
/* do something to the args
...
... */
return LIB_do_it_ptr(arg1, arg2);
}
do_it_ptr需要一個指向需要3個字符參數的函數的指針;你爲只有2個字符參數的函數分配函數指針。 doit()的extern聲明幾乎不需要。 do_it_ptr不是必需的;你可以在你當前傳遞do_it_ptr的地方通過名字傳遞do_it。等等! – 2008-12-25 06:18:52
如@litb所述,dlopen()
函數主要在使用ELF格式對象文件的系統上提供。它相當強大,並且可以讓您控制是否可以從主程序中滿足加載庫引用的符號,並且通常會讓它們滿意。並非所有的共享庫加載系統都是靈活的 - 請注意是否需要移植代碼。
@hhafez概述的回調機制現在可以工作,該代碼中的扭結被理順了。
- 1. 如何在調試Visual C++程序時禁用符號加載?
- 2. 如何在主應用程序中使用數組參數調用函數?
- 3. 共享庫(.so)如何調用在其加載程序中實現的函數?
- 4. 遠程調試MVC 6應用程序:符號未加載。
- 5. 如何在Web應用程序中加載國家數據庫
- 6. 信號處理程序沒有在主函數中調用
- 7. 引導加載程序函數調用
- 8. 如何從Flex中的主應用程序加載子應用程序
- 9. 從Arduino的庫中調用主程序中的函數
- 10. 如何在ajax應用程序中加載Angularjs應用程序?
- 11. 如何在控制檯應用程序主要方法中調用javascript函數
- 12. 數據庫如何加載到應用程序中?
- 13. 如何在聊天應用程序中添加表情符號
- 14. 如何在Android應用程序中重複調用函數?
- 15. 如何在Cordova中安裝應用程序時調用函數
- 16. 無法在VS 2010上加載Silverlight應用程序的符號
- 17. 如何從主程序中的函數調用列表?
- 18. 如何在MFC應用程序中加載VC++ CLR庫?
- 19. 如何在我的Flex應用程序的swfLoader中加載的swf文件中調用actionscript函數?
- 20. 如何在應用程序加載時調用一個xib?
- 21. 如何在C++中調用主函數
- 22. 如何不斷調用WPF應用程序中的函數
- 23. 如何在Metro應用程序中插入數學符號
- 24. 如何在外部node.js應用程序中重載函數?
- 25. 如何從PluginKit加載數據庫應用程序
- 26. 如何在網絡應用程序啓動時在openshift中加載函數
- 27. 如何在VCL窗體應用程序中調用和調用函數
- 28. 如何調試到iOS應用程序的XIB加載過程?
- 29. 使用gdb跟蹤外國的android程序或應用程序 - 加載符號?
- 30. 如何在MATLAB中調用主函數中的函數?
下面的答案在回答這個問題方面做得很好,但我必須問 - 你能否解釋這個要求的更廣泛的背景?當我發現需要這樣做時,要麼是構建一個可擴展性/插件模型,要麼是因爲我的程序不是很好的考慮因素。 – reuben 2008-12-25 06:18:56
它也可以用於倒置控制,不是嗎?定義應用程序在庫中的流程,而實際的實現在主應用程序中 – hhafez 2008-12-25 11:19:16
想象一下Perl XS模塊。它需要使用低級別的Perl函數(比如說newSViv()從一個整數中創建一個SV);如果模塊使用Perl的newSViv()函數,而不是將其自己的副本嵌入到模塊的共享對象中,則很方便。此外,代碼需要標準的C庫。 – 2008-12-25 19:35:29