它似乎可以在Windows和Linux上正常工作,使用GetProcAddress()或dlsym()來返回一個填充有函數指針的結構,以便從動態庫中使用。如何從共享/動態庫中加載符號表結構?
...但是,似乎有大量的人提出問題並抱怨鑄造void *指向函數指針,並且談論使用dlfunc,當這種相對簡單的方法似乎工作得很好時。
那麼,你有什麼特別的理由不想這樣做嗎?
像這樣的代碼由於某種原因不可移植嗎?
我意識到這種方法只適用於共享明確命名的函數和綁定函數,但加載插件這就好,因爲我擔心......?
header.h:
/* C++ safety & windows support */
#ifdef __cplusplus
#if _WIN32 || _WIN64
#define __EXT extern "C" __declspec(dllexport)
#else
#define __EXT extern "C"
#endif
#else
#if _WIN32 || _WIN64
#define __EXT __declspec(dllexport)
#else
#define __EXT extern
#endif
#endif
struct a_sym_table {
int (* action) (int argc, char *argv[]);
};
__EXT struct a_sym_table liba_symbols;
由source.c:
int perform_action_lib_a(int argc, char *argv[]) {
int rtn = perform_action_lib_b() + perform_action_lib_c();
return(rtn);
}
struct a_sym_table liba_symbols = {
&perform_action_lib_a
};
編輯:只是爲了清楚起見,明顯代碼負載符號將在不同平臺上的不同,但是這種方法允許共享庫可以被移植到不同的平臺而無需改變。
這就是我在談論的時候,我問,是否有一個原因,你不會這樣做?
我想知道的是,如果有一些很好的理由不構成你的共享庫像這樣可移植性緣故。
IIRC,'dlfcn.h'是POSIX(POSIX.1-2001)的一部分,所以它應該非常便攜。即使是一些更新的Windows。 – peterph
真正的問題是符合標準的C禁止在void *和函數指針之間進行投射;一個*一些*系統,如linux,可以工作,但在其他系統上它不會(BSD),您必須改用dlfcn。在這個問題上有大量的線程。 - 我只是想盡量減少#如果我必須使用這種方式。 – Doug
但你不是在void和函數指針之間進行投射。你在一個void和一個結構指針之間進行投射。該結構包含一個函數指針。至少這就是你在示例代碼中展示的內容。 – Art