函数指针:*(void**) (&fun) = dlsym(lib, "fun") 它是如何工作的?

Posted

技术标签:

【中文标题】函数指针:*(void**) (&fun) = dlsym(lib, "fun") 它是如何工作的?【英文标题】:Function pointers : *(void**) (&fun) = dlsym (lib, "fun") how its work? 【发布时间】:2014-05-01 12:36:37 【问题描述】:

我正在使用 dlsym 填充函数指针,它是调用的成员变量。 如下所示

class ABC 
private: 
    void (*m_fun) (int);

现在如果我分配

m_fun = (void*) dlsym (libHandle, "fun") 

报错

我在网上找到了

*(void**) (&m_fun) = dlsym(libHandle, "fun") is working. 

谁能告诉我这里的转换/转换是如何发生的?

【问题讨论】:

我不想使用 m_fun = (void*) (int) dlsym..... 【参考方案1】:

演员说:

获取指向函数的指针 获得指向那个的指针 假设该指针指向常规对象指针 (void*) 而不是函数指针 通过该指针写入dlsym返回的地址,从而将函数指针设置为该地址

这解决了(通常是可取的)限制,即您不能将函数指针分配给对象指针。由于这是 C++,你可以这样写:

reinterpret_cast<void*&>(m_fun) = dlsym(libHandle, "fun");

这可能更清楚一点:假装m_funvoid*,然后写信给它。

请注意,这比将dlsym 的结果转换为正确的类型并分配它更不便携:

m_fun = reinterpret_cast<void(*)(int)>(dlsym(libHandle, "fun"));

在任何平台上都可以正常工作,或者给出编译器错误。您的狡猾演员可能会在具有非统一内存架构的平台上导致未定义的运行时行为。

【讨论】:

如果函数指针和void* 不能相互转换,那么该平台可能不会有任何dlsym 实现。 @aschepler:确实如此。但是转换可能很重要,在这种情况下,转换分配目标而不是 dlsym 的结果可能会做错事 dlsym 是 specified by POSIX,而 POSIX 需要将 void* 转换为函数指针才能工作。 @larsmans:确实;但是*(void**)p = void_pointer 绕过了该转换,因此如果转换不重要,可能会做错事。【参考方案2】:

Void* 只是一个内存指针。要使用函数指针指向函数,首先需要一个指向实际函数的指针,然后需要指针的其余部分 (**) 指向变量和函数体。

【讨论】:

以上是关于函数指针:*(void**) (&fun) = dlsym(lib, "fun") 它是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

函数参数是二级指针的问题

C语言中函数指针

STM32bootload——typedef void (*Fun) (void) 理解

C/C++语法和用法技巧(指针)

二级指针分析 -- (int *)*(&b)

二级指针分析 -- (int *)*(&b)