2012-05-09 17 views
2

代碼來源於此頁:http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html請問這個是有意義的:*(無效**)(FPTR)=的dlsym(手柄, 「創建my_function」);`

你能幫我明白這一點? 它將函數指針的地址轉換爲void **,然後對其進行解引用。我不知道爲什麼它要這樣工作。

我感謝您的幫助!到目前爲止,我得到的唯一建議是「從右向左讀」或類似「從右向左循環讀取」。

+2

我也無法理解它。我已經使用過'fptr =(fptr_t)dlsym(...)',其中'fptr_t'是'fptr'的實際類型。 – vhallac

+0

@vhallac:POSIX備註/例子的作者聲稱C標準要求你的演員生成警告。但是我在C標準中找不到這樣的要求。這就是他們按照自己的方式編寫它的原因,但請參閱我的答案,瞭解他們爲何解決方案無效。 –

+0

@R ..我確實(你的答案和他們的理由)。說實話,我從來沒有把這看作是一個問題。感謝您的回答。今天我學到了一些關於C的新東西。 :) – vhallac

回答

10

代碼的含義是:

  1. fptr地址。此表達式的類型是指向函數的指針(某些特定類型的函數)。
  2. 將指針表達式轉換爲「指向void的指針的指針」。
  3. 取消引用訪問對象fptr的指針,就好像它是void *類型的對象一樣。
  4. 指定的在步驟3得到

不幸的左值的權利,在誰POSIX寫這個例子是對裂紋的結果,因爲步驟3違反了C語言的別名規則,因此調用未定義行爲。特別是,真實世界編譯器將以打破預期用法的方式優化此代碼。

什麼這個例子的作者是試圖實現了避免因指針鑄造右側作廢函數指針。這是基於一個聲明,即C標準要求這個演員發出警告,但我已經徹底搜尋了這樣的要求,並且沒有找到這樣的要求。

如果這樣的問題確實存在(警告要求),那麼唯一的辦法,以沉默的警告,而不必調用未定義的行爲(如在POSIX的文本中的壞榜樣)是這樣做:

void (*fptr)(); // or whatever function pointer type you want 
void *temp = dlsym(handle, "my_function"); 
memcpy(&fptr, &temp, sizeof fptr); 
1

該函數返回一個函數指針。該代碼說,嘿,讓我的函數指針變量給我的地址。將它投射到void **。現在請遵循void **並將void * =的值設置爲從通話中獲得的指針。

0

*(void **)(&fptr) = dlsym(handle, 「my_function」);

爲了簡便,

fptr是一個指針。

&fptr是該指針的地址。

你這類型轉換到pointer to a pointer to a void

,然後引用,並指定從函數的返回值。

相關問題