2

コードはこのページからのものです: http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html

これを理解するのを手伝ってもらえますか? 関数ポインターのアドレスを取得し、それを void** にキャストしてから逆参照します。なぜこのように機能しなければならないのかわかりません。

私はあなたの助けに感謝します!今まで私が受けたアドバイスは、「右から左に読んでください」または「右から左にサイクルで読んでください」のようなものだけでした。

4

3 に答える 3

10

コードの意味は次のとおりです。

  1. のアドレスを取得しますfptr。この式の型は、ポインターから関数へのポインター (特定の型) です。
  2. そのポインター式を「void へのポインターへのポインター」にキャストします。
  3. そのポインターを逆参照してfptr、オブジェクトが type のオブジェクトであるかのようにアクセスしますvoid *
  4. 権利の結果を手順 3 で取得した左辺値に代入します。

残念なことに、この例を POSIX で書いた人は、ステップ 3 が C 言語のエイリアシング規則に違反しているため、未定義の動作を引き起こすため、問題を抱えていました。特に、実際のコンパイラは、意図した使用法を破る方法でこのコードを最適化します。

この例の作成者が達成しようとしていたのは、右辺をポインターから voidへ、ポインターから関数へとキャストすることを回避することでした。これは、C 標準では警告を生成するためにこのキャストが必要であるという主張に基づいていますが、そのような要件を徹底的に検索しましたが、そのような要件は見つかりませんでした。

そのような問題が実際に存在する場合 (警告の要件)、未定義の動作 (POSIX のテキストの悪い例のように) を呼び出さずに警告を黙らせる唯一の方法は、次のようにすることです。

void (*fptr)(); // or whatever function pointer type you want
void *temp = dlsym(handle, "my_function");
memcpy(&fptr, &temp, sizeof fptr);
于 2012-05-09T15:39:53.493 に答える
1

関数は関数ポインタを返します。そのコードは、私の関数ポインター変数を取り、そのアドレスを教えてくれると言います。にキャストしvoid **ます。次に、を参照void **して、void * = の値を呼び出しから取得したポインターに設定します。

于 2012-05-09T15:39:43.827 に答える
0

*(void **)(&fptr) = dlsym(handle, “my_function”);

これを簡単にするために、

fptrポインタです。

&fptrそのポインタのアドレスです。

あなたはそれを型キャストしていますpointer to a pointer to a void

関数からの戻り値を参照して代入します。

于 2012-05-09T16:08:24.200 に答える