2017-03-22 68 views
2

的情况下,我创建一个使用dlsysm(剪切对象开放),但我收到以下错误:错误:从无效转换`无效*`来`无效(*)()`在dlsysm

error: invalid conversion from "void*" to "void (*)()"

这里是我的代码:

#include<iostream> 
#include<dlfcn.h> 
using namespace std; 

int main() { 
    void (*fnptr)(); 
    void *handle; 

    handle = dlopen("./libtestshared.so",RTLD_LAZY); 
    if (!handle) { 
     cerr << "Cannot open library: " << dlerror() << '\n'; 
    } else { 
     cout<<"Opening"<<'\n'; 
    } 

    fnptr = dlsym(handle , "fun"); 

    return 0; 
} 
+0

你可以请提供的代码,你得到的错误?很难看到这里发生了什么 – Stefano

+0

#include #include using namespace std; int main() { void(* fnptr)(); void * handle; handle = dlopen(“./ libtestshared.so”,RTLD_LAZY); if(!handle) cerr <<“无法打开库:”<< dlerror()<<'\ n'; } else { cout <<“Opening”<<'\ n'; } fnptr = dlsym(handle,“fun”); return 0; } – Yugandhar

+0

好的...我已经添加了格式为您的代码... – Stefano

回答

0

我从来没有使用的dlsym但在这里,他有什么manpage说:

The function dlsym() takes a "handle" of a dynamic library returned by dlopen() and the null-terminated symbol name, returning the address where that symbol is loaded into memory.

那么什么是回报不是函数指针,而是标准指针!下面的东西应该工作:

void* returnedAddress = dlsym(handle , "fun"); 
fnptr = reinterpret_cast<void(*)()>(returnedAddress); 
+0

这不是TS想要的:他删除了自己的评论,但他期望返回的地址是函数指针。所以'undefined'指针(imho没有像“标准”指针那样的东西)需要被转换为正确的类型。 – JHBonarius

+0

我修复了我的答案...谢谢 – Stefano

+0

我修改了我的代码void * returnedAddress = dlsym(handle,“fun”); fnptr = reinterpret_cast (returnedAddress);但我正在分段错误。通过分析核心句柄= 0(即在采样过程中的main()中#1 0x080487d8.cpp:23 fnptr = 0x8048418 句柄= 0x0 returnedAddress = 0x82ee020) – Yugandhar

2

A void *是不兼容的函数指针。

流延在这种情况下需要:

fnptr = (void (*)())dlsym(handle , "fun"); 
+0

虽然正确,但这是C风格的强制转换。我认为从C++的角度来看,昆汀的答案更好。见[link](http://www.cplusplus.com/doc/tutorial/typecasting/)。 – JHBonarius

+0

当我调用fnptr分段错误发生时。 0x080487d8 main()在sampledlopen.cpp中:21 fnptr = 0 handle = 0xa048020 – Yugandhar

+0

@Yandandhar你的fnptr为零(即null),所以你调用一个空指针。 –

4

dlsym可以返回一个指向任何签名的函数,它的设计者选择回到不透明void*。当然,dlsym的工作原理是这样一个void*然后可以安全地转换为正确的函数指针类型。这是做如下:

auto fnptr = reinterpret_cast<void(*)()>(dlsym(handle , "fun")); 
+0

只有你通过添加'auto'关键字来做出答案C++ 11) – JHBonarius

+0

@ J.H.Bonarius你是什么意思? – Quentin

+0

直到C++ 11才添加'auto'关键字。虽然TS可能使用了新的编译器,但是旧的编译器不会支持它。在TS的情况下,他已经定义了'fnptr'earlier(c-style;)),你甚至可以在你的答案中忽略它。 – JHBonarius