我正在阅读dlopen和FreeBSD上的朋友的手册页。我正在开发一个跨平台应用程序,它使用共享库作为可加载插件。我以前从未这样做过,但我想我对它的工作原理有一个很好的了解。手册页提到了dlsym(),它似乎是从共享库获取函数指针的常用方法;dlfunc(),它据称避免了编译器对将void*投射到函数指针的抱怨。dlsym()更常见的原因是什么(可移植性?)?我想知道是使用dlfunc()来避免编译器问题,还是使用dlsym()。dlfunc()是否可移植?

最佳答案

您不能期望在其他unix上提供dlfunc,但它的实现是直接的和可移植的。你可以这样做

# 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,那么其他build+配置系统可能具有类似的功能。(dlsym更为广泛。)
这就是说,我认为编译器警告是愚蠢的-C标准没有,但POSIX保证void *指针可以安全地表示所有函数指针…

关于c - dlfunc的可移植性?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1144107/

10-11 16:43