1

我正在阅读 FreeBSD 上 dlopen 和朋友的联机帮助页。我正在开发一个跨平台应用程序,该应用程序将共享库用于可加载插件。我以前从未这样做过,但我认为我对它的工作原理有相当的了解。手册页提到了 dlsym(),这似乎是从共享库中获取函数指针的常用方法,以及 dlfunc(),据说它可以避免编译器抱怨将 void* 转换为函数指针。dlsym() 更常见(可移植性?)是否有原因?我想知道是否应该使用 dlfunc() 来避免编译器问题,或者使用 dlsym()。dlfunc() 是可移植的吗?

4

2 回答 2

3

您不能指望dlfunc在其他 UNIX 上提供一个,但它的实现简单且可移植。你可以做类似的事情

# configure.ac
AC_SYSTEM_EXTENSIONS
AC_CHECK_FUNCS([dlfunc])

// some common header
#include "config.h"
#ifndef HAVE_DLFUNC
/* copied from FreeBSD, source/include/dlfcn.h */
struct __dlfunc_arg {
        int __dlfunc_dummy;
};
typedef void (*dlfunc_t)(struct __dlfunc_arg);
dlfunc_t dlfunc(void *restrict handle, void *restrict symbol);
#endif

// some source file
#include "config.h"
#ifndef HAVE_DLFUNC
/* copied from FreeBSD, lib/libc/gen/dlfunc.c */
dlfunc_t dlfunc(void *restrict handle, void *restrict symbol) {
        union {
                void *d;
                dlfunc_t f;
        } rv;
        rv.d = dlsym(handle, symbol);
        return rv.f;
}
#endif

如果您使用的是 Autoconf,并且其他构建+配置系统可能具有类似的能力。(dlsym更广泛使用。)


话虽如此,我认为编译器警告很愚蠢——C 标准没有,但 POSIX 保证void *指针可以安全地表示所有函数指针……

于 2009-07-17T16:14:04.783 回答
1

当您说跨平台时,您是指跨 POSIX 平台还是您也需要 Windows 支持?

如果您使用 C++ 工作,您可以查看Boost.Extension 提案代码。这需要注意 Windows 与 UNIX 的可移植性。

如果您正在寻找仅限 UNIX 的建议,请查看Single UNIX Specification

据我所知,dlsym 是标准的 UNIX 做事方式。Windows 有一个等效但完全不同的做事方式。

于 2009-07-17T16:01:00.817 回答