在 windows 和 linux 上使用 GetProcAddress() 或 dlsym() 返回一个填充有函数指针的结构,以便从动态库中使用,这似乎可以正常工作。

...但是,似乎有很多人提出问题并提示将 void * 指针转换为函数指针,并谈论使用 dlfunc,而这种相对简单的方法似乎工作得很好。

那么,您有什么特别的理由不想这样做吗?

像这样的代码出于某种原因不可移植吗?

我意识到这种方法仅适用于共享显式命名的函数和绑定(bind)函数,但对于加载插件就我而言很好......?

标题.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;

来源.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
};

编辑:为了清楚起见,显然不同平台上加载符号的代码会有所不同,但这种方法允许共享库无需更改即可移植到不同平台。

这就是我在问时所说的,你有什么理由不这样做吗?

我想知道的是,是否有充分的理由为了可移植性而不像这样构建共享库。

最佳答案

您正在访问共享库中的数据。这就是 dlsym() 的用途。动态链接器应该能够很好地处理传递库边界的函数指针。至少在类 Unix 系统上。我不了解 Windows,但我可以想象如果某些类型的指针有效而其他类型的指针无效,那么很多事情都会中断。

当谈到可移植性时,您已经被限制在具有“#if _WIN32 || _WIN64”后面的东西或实现 dlsym 的系统。这应该已经暗示你正在做的事情是通过测试而不是遵循一些严格的标准文件来工作的。所以你可以移植到“无论它适用于什么”。

关于c - 从共享/动态库加载符号表结构的可移植性如何?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13375523/

10-13 08:28
查看更多