_adopt_thread

提供: RAD Studio
移動先: 案内検索

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++

+