它似乎可以在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