2017-03-22 69 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