_adopt_thread
process.h:インデックス への移動
ヘッダーファイル
process.h
カテゴリ
プロセス制御ルーチン
プロトタイプ
_PTHREAD_ADOPTION_DATA _adopt_thread(void (_USERENTRY *__start_address)(void *), void * __arglist, int free_flag );
説明
必要な内部データ(例外,スタック情報など)をフックアップすることで,Windows API CreateThread 関数によって作成されたスレッドを C++Builder RTL に受け入れます。このように,_adopt_thread は,RTL がそのスレッドの例外を処理できるようにします。次に,このスレッドの実行パスは,別の関数(アダプティブスレッド関数)に転送されます。RTL の側からは,このアダプティブスレッド関数の実行中,スレッドが _beginthreadex の呼び出しによって作成されているかのように見え,ほかの RTL 関数の呼び出し,例外の送出/捕捉などのすべての機能が許可されます。
スレッドを作成する場合は,通常,_beginthread を呼び出します。これは,内部データを自動的にフックアップします。_adopt_thread は,この内部データが存在しない場合に主に使用されます。たとえば,ISAPI などの外部ソースで作成されたスレッドからユーザーが呼び出される場合です。
_adopt_thread を使用すると,C++Builder でコンパイルした DLL を C++Builder 以外の EXE から使用できます。_adopt_thread は次のように動作します。
- ユーザー関数を呼び出す(arglist パラメータで渡す)
- 例外情報をアンフックする
- スレッドコンテキストのハンドルを返す
この処理により,データをすべて割り当て直さなくても,同じ関数を再度使用できます。この処理の最後に _unadopt_thread 関数を呼び出すと,この残りのデータを最終的に解放できます。
最後のパラメータ free_flag は,関数の終了時にスレッドデータ構造体を解放するかどうかを決定します。
- free_flag が 0 の場合,アダプティブ関数が終了すると,その例外ハンドラだけがアンフックされます。スレッドの受け入れ時に割り当てられた RTL 固有のデータの残りの部分は,有効なままです。その後,同じスレッドが _adopt_thread を再度呼び出すと,既存のデータが使用され,例外ハンドラが再度フックされ,指定されたアダプティブスレッド関数が呼び出されます。
- free_flag が 0 以外の値に設定されている場合は,_adopt_thread が戻る前にスレッドデータ構造体が解放されます。この場合,関連するデータがすでに解放されているため,返されるスレッドハンドルは NULL になります。
戻り値
__free_flag パラメータが false(0)の場合,_adopt_thread は,ハンドル(スレッドコンテキスト)を返します。このハンドルを後で _unadopt_thread() に渡して,データ構造体を解放できます。
_adopt_thread の __free_flag パラメータが 0 以外の値の場合は,_adopt_thread が戻る前にスレッドデータが解放され,返されるハンドルは NULL になります。
エラーが発生した場合は,errno が次の値に設定されます。
ENOMEM - メモリが不十分
コード例
#include <process.h> #include <windows.h> void adopted_thread(void*) { printf("Running in a RTL-managed thread!\n"); } unsigned long __stdcall winapi_thread(void*) { /* This code runs on another thread, created by CreateThread Win32 API. _adopt_thread is used to continue the execution in the routine that is RTL managed (in the same thread context). */ printf("Running in a simple thread! Adopting ...\n"); _PTHREAD_ADOPTION_DATA data = _adopt_thread(adopted_thread, NULL, false); /* Un-adopt the thread and release it's resources */ printf("Back to OS thread! Release adoption ...\n"); _unadopt_thread(data); } int _tmain(int argc, _TCHAR* argv[]) { /* Create a thread using OS APIs, thus RTL-unmanaged */ unsigned long threadId; CreateThread(NULL, 0, winapi_thread, NULL, 0, &threadId); Sleep(100); return 0; }
移植性
POSIX | Win32 | ANSI C | ANSI C++ |
---|---|---|---|
+ |