C ++ Builder2009でポインターをvoid *からTMemo *に正しくダウンキャストするにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/274841

質問

C ++ Builder 2009でマルチスレッドソケットチャットを書いています。
それは私がする必要があることに従ってほぼ完了していますが、私には少し問題があります。 TMemo *ポインターをCreateThread WinAPI関数に渡して、void *にアップキャストする必要があります。

この方法で試しました:

HANDLE xxx = MemoChat->Handle;
hNetThread = CreateThread(NULL, 0, NetThread, xxx, 0, &dwNetThreadId);
//...

そしてNetThread関数で、

TMemo* MyMemo((HANDLE)lpParam);
TMemo* MyMemo((TMemo*)lpParam);

しかし、うまくいきませんでした:(

問題は、この新しいスレッドでメモコンポーネントを使用できるように、本当に正しくダウンキャストする方法ですか?

役に立ちましたか?

解決

電話:

TMemo*     MemoChat   = // You defined that somewhere I assume
HANDLE     hNetThread = CreateThread(NULL, 0, NetThread, MemoChat, 0, &dwNetThreadId);

ここで起こっているのは、3番目のパラメーターとして渡すポインターが、voidポインター(またはWinTerms LPVOID)に自動的に変換されることです。システムはオブジェクトについて何も知らないので、タイプ情報を失うだけで、それは変更されません。

新しいスレッドスタートポイント:

DWORD NetThread(LPVOID lpParameter)
{
    TMemo*   MemoChat   = reinterpret_cast<TMemo*>(lpParameter);
    // Do your thread stuff here.
}

スレッド開始メソッドが呼び出されると。 voidポインターを正しい型に戻すだけで、再び使用できるようになります。

他の誤解を解消するためだけに。

A ハンドルはポインターです
そして、NetThread()にパラメーターとして渡すこともできます。

ハンドルは、使用しているオブジェクトを指すシステム制御下のポインターへのポインターです。それで、なぜ二重の間接化。これにより、システムはオブジェクトのすべての所有者を見つけることなく、オブジェクトを移動(およびポインターを更新)できます。所有者はすべて、更新されたばかりのポインターを指すハンドルを持っています。

これは、OS /ハードウェアがメインメモリをセカンダリストレージにスワップする機能があるため、現代のコンピューターではめったに使用されない昔ながらのコンピューターサイエンスの概念です。しかし、特定のリソースに対してはまだ有用です。今日、ハンドルが必要な場合、ハンドルはユーザーから離れたオブジェクト内に隠されています。

他のヒント

ハンドルは ポインターではなく、Win32 APIの概念であることを理解してください。したがって、最初の行はLPVOIDをHANDLEにキャストします。これは正しいことです。スレッドルーチンのパラメーターは実際にはハンドル(xxx)として与えられるためです。ただし、その後、ハンドルをMyMemoオブジェクトに変換します。これは、ハンドル内のビットをアドレスを形成するかのように扱いますが、そうではありません。

2行目はまったく同じ変換を行います。ハンドルを直接ポインタであるかのように扱います。

MemoChat自体をスレッドに渡さないのはなぜかと思います:

hNetThread = CreateThread(NULL, 0, NetThread, MemoChat, 0, &dwNetThreadId);

これは、ハンドルとポインタの関係を明確にするためのものです。Martinが正確に正しいとは思わないからです。

&quot;ポインタへのポインタ&quot;これは実際にハンドルと呼ばれ、オペレーティングシステムがヒープに割り当てられたメモリブロックを、ハンドルを介して常にアクセスするアプリケーションレイヤーの明示的な知識なしに物理的に移動できるようにする一般的なCSアプローチです。 Classic 68K Mac OSはこのように機能します。このように動作するOSでは、通常、ユーザーコードがハンドルを介してメモリを割り当てたり、ヒープから直接メモリを割り当てたりすることができます。このアプローチは、適切なメモリ管理ハードウェアを搭載していないマシンで使用されます。

ただし、HANDLEという単語には、以前の使用の抽象化の一部を借用する他の使用方法がありますが、実装は異なります。不透明なポインター(ユーザーが知識のないデータ構造へのポインター-PIMPLイディオム)は、一般にハンドルとも呼ばれます。

また、HANDLEという用語は、単に「参照」を示すために使用できます。オブジェクトへ-おそらく配列へのインデックス。 Unixファイルハンドル(=ファイル記述子)は、この良い例です。 stdin = 0、stdout = 1、...

では、上記のうちWindows APIハンドルはどれですか?矛盾するレポートを見てきました。 このドキュメントの説明:

  

Win32のハンドルは、   リソースまたはウィンドウを識別します。彼ら   へのポインターまたはポインターではありません   ポインター。 ID番号と考えてください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top