3

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

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

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

由于某种原因,这样的代码是否不可移植?

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

标头.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
};

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

这就是我要问的问题,你有理由不这样做吗?

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

4

1 回答 1

3

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

在可移植性方面,您已经被限制在具有“#if _WIN32 || _WIN64”背后已有的东西或实现dlsym的系统中。这应该已经暗示您正在做的事情是通过测试而不是遵循一些严格的标准文档来实现的。因此,您可以移植到“无论它如何工作”。

于 2012-11-14T10:53:40.843 回答