> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# エンティティハンドル

> PlayFab C SDK で認証済みプレイヤーおよびタイトルの呼び出しに使用する PFEntityHandle 資格情報、参照カウント、エンティティトークンのライフタイムを管理します。

**PFEntityHandle** は、PlayFab サービス呼び出しを行うための主要な資格情報です。認証済みエンティティ (プレイヤー (title\_player\_account) またはタイトルのいずれか) を表し、SDK がリクエストを承認するために必要なエンティティトークンを保持します。すべてのログインまたは認証呼び出しは **PFEntityHandle** を返し、すべてのサービス呼び出しではそれが必要です。

## エンティティハンドルの取得

エンティティハンドルは直接作成しません。代わりに、ログインまたは認証呼び出しの成功時の出力として取得します。

**プレイヤーログイン (Windows の例):**

```cpp theme={null}
PFAuthenticationLoginWithXUserRequest request{};
request.createAccount = true;
request.user = userHandle; // XUserHandle from XUserAddAsync

XAsyncBlock async{};
HRESULT hr = PFAuthenticationLoginWithXUserAsync(serviceConfigHandle, &request, &async);
hr = XAsyncGetStatus(&async, true);

PFEntityHandle entityHandle{ nullptr };
size_t bufferSize{};
hr = PFAuthenticationLoginWithXUserGetResultSize(&async, &bufferSize);

std::vector<char> loginResultBuffer(bufferSize);
PFAuthenticationLoginResult const* loginResult{};
hr = PFAuthenticationLoginWithXUserGetResult(
    &async, &entityHandle,
    loginResultBuffer.size(), loginResultBuffer.data(),
    &loginResult, nullptr);
```

**タイトルエンティティ (サーバー):**

タイトルエンティティは、ユーザー資格情報の代わりにシークレットキーで認証します。返された **PFEntityHandle** は同じように機能しますが、プレイヤーではなくタイトルを表します。詳細については [タイトルエンティティで PlayFab にアクセスする](/services/playfab/sdks/c/server) を参照してください。

## ハンドル所有権と参照カウント

**PFEntityHandle** は参照カウント方式です。ログイン呼び出しでハンドルを受け取ると、1つの参照を所有します。[**PFEntityDuplicateHandle**](/services/playfab/api-references/c/pfentity/functions/pfentityduplicatehandle) で追加の参照を作成し、[**PFEntityCloseHandle**](/services/playfab/api-references/c/pfentity/functions/pfentityclosehandle) で解放できます。基になるエンティティオブジェクトは、最後の参照が閉じられたときにのみ破棄されます。

**ルール:**

* ログインの `GetResult` 関数または **PFEntityDuplicateHandle** を呼び出すたびに、閉じる必要のあるハンドルが与えられます。
* ハンドルを閉じても、同じエンティティへの他のハンドルは無効になりません。
* [**PFServicesUninitializeAsync**](/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync) を呼び出す前に、すべてのハンドルを閉じてください。

```cpp theme={null}
// Duplicate a handle for another component
PFEntityHandle secondHandle{ nullptr };
HRESULT hr = PFEntityDuplicateHandle(entityHandle, &secondHandle);

// Both handles are independently valid
// ...

// Each owner closes their own handle
PFEntityCloseHandle(secondHandle);
PFEntityCloseHandle(entityHandle);
```

## エンティティ情報の取得

### エンティティキー

エンティティキーはエンティティ (そのタイプと ID) を識別します。2回の呼び出しパターンを使用します: まずサイズを取得し、次にデータを取得します。

```cpp theme={null}
size_t size{};
HRESULT hr = PFEntityGetEntityKeySize(entityHandle, &size);

std::vector<char> buffer(size);
PFEntityKey const* entityKey{};
hr = PFEntityGetEntityKey(entityHandle, buffer.size(), buffer.data(), &entityKey, nullptr);

// entityKey->type is "title_player_account" for players
// entityKey->id is the entity's unique ID
```

### エンティティトークン

エンティティトークンはサービス呼び出しを承認します。SDK はトークンを自動的に管理しますが、必要に応じて現在のトークンを取得できます。

```cpp theme={null}
XAsyncBlock async{};
HRESULT hr = PFEntityGetEntityTokenAsync(entityHandle, &async);
hr = XAsyncGetStatus(&async, true);

size_t size{};
hr = PFEntityGetEntityTokenResultSize(&async, &size);

std::vector<char> buffer(size);
const PFEntityToken* entityToken{};
hr = PFEntityGetEntityTokenResult(&async, buffer.size(), buffer.data(), &entityToken, nullptr);

// entityToken->token is the token string
// entityToken->expiration is the optional expiration time (UTC)
```

### エンティティタイプの確認

エンティティキーのタイプ文字列を検査する代わりに、[**PFEntityIsTitlePlayer**](/services/playfab/api-references/c/pfentity/functions/pfentityistitleplayer) を素早い確認として使用してください:

```cpp theme={null}
bool isTitlePlayer{};
HRESULT hr = PFEntityIsTitlePlayer(entityHandle, &isTitlePlayer);
```

## プレイヤーエンティティとタイトルエンティティ

プレイヤーエンティティとタイトルエンティティは両方とも **PFEntityHandle** を使用しますが、実行できる内容が異なります:

|                                                                                                          | プレイヤーエンティティ                                         | タイトルエンティティ                                    |
| -------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | --------------------------------------------- |
| **取得方法**                                                                                                 | ログイン呼び出し (例: `PFAuthenticationLoginWithXUserAsync`) | `PFAuthenticationGetEntityWithSecretKeyAsync` |
| **エンティティタイプ**                                                                                            | `title_player_account`                              | `title`                                       |
| [**PFEntityIsTitlePlayer**](/services/playfab/api-references/c/pfentity/functions/pfentityistitleplayer) | `true` を返す                                          | `false` を返す                                   |
| [**PFEntityGetSecretKey**](/services/playfab/api-references/c/pfentity/functions/pfentitygetsecretkey)   | `E_PF_NOSECRETKEY` で失敗する                            | シークレットキーを返す                                   |
| **利用可能な API**                                                                                            | Client プレフィックス付きおよびプレフィックスなし API                    | Server プレフィックス付きおよびプレフィックスなし API              |

プレフィックスなし API (例: Inventory、Leaderboards、Data) は、ドキュメントで明記されていない限り、プレイヤーエンティティとタイトルエンティティの両方から呼び出すことができます。Client プレフィックス付き API はプレイヤー専用、Server プレフィックス付き API はタイトル専用です。

**PFEntityGetSecretKey** は、タイトルエンティティに関連付けられたシークレットキーを取得します。プレイヤーエンティティはシークレットキーを持たないため、失敗します。

```cpp theme={null}
size_t keySize{};
HRESULT hr = PFEntityGetSecretKeySize(entityHandle, &keySize);
if (SUCCEEDED(hr))
{
    std::vector<char> secretKey(keySize);
    hr = PFEntityGetSecretKey(entityHandle, secretKey.size(), secretKey.data(), nullptr);
}
```

<Note>
  **PFEntityGetSecretKey** は Windows、Linux、macOS プラットフォームでのみ利用できます。
</Note>

## トークンイベントハンドラー

SDK はエンティティトークンが期限切れになる前に自動的に更新します。これらのイベントを監視するためのコールバックを登録できます。

### トークン期限切れ

自動更新に失敗した場合 (たとえば、元のログイン資格情報がもはや有効でない場合)、SDK はトークン期限切れイベントを発生させます。ハンドラーを登録して、新しい資格情報を提供し、ログインを再試行します。

```cpp theme={null}
PFRegistrationToken registrationToken{};
HRESULT hr = PFEntityRegisterTokenExpiredEventHandler(
    nullptr,  // XTaskQueueHandle, or nullptr for default
    nullptr,  // optional context
    [](void* ctx, PFEntityKey const* entityKey)
    {
        // Re-authenticate the player with a fresh credential
        // See relogin.md for a complete example
    },
    &registrationToken);
```

### トークン更新

SDK がバックグラウンドでトークンを正常に更新したときに知りたい場合は、トークン更新ハンドラーを登録します。これは情報提供のみで、特に対応する必要はありません。

```cpp theme={null}
PFRegistrationToken registrationToken{};
HRESULT hr = PFEntityRegisterTokenRefreshedEventHandler(
    nullptr,  // XTaskQueueHandle, or nullptr for default
    nullptr,  // optional context
    [](void* ctx, PFEntityKey const* entityKey, const PFEntityToken* newToken)
    {
        // Log the refresh or update cached token references
    },
    &registrationToken);
```

### 登録と登録解除のタイミング

* **登録** はハンドラーを早期に、SDK 初期化直後およびログイン前に行います。これによってイベントを見逃さないようにします。
* **登録解除** はシャットダウン中、エンティティハンドルを閉じる前に行います。

```cpp theme={null}
PFEntityUnregisterTokenExpiredEventHandler(expiredRegistrationToken);
PFEntityUnregisterTokenRefreshedEventHandler(refreshedRegistrationToken);
```

トークンの期限切れ処理と再ログインの完全なウォークスルーについては、[トークン期限切れの処理](/services/playfab/sdks/c/relogin) を参照してください。

## ユーティリティアクセサー

エンティティハンドルから API エンドポイントとタイトル ID を取得できます。これらは、ログイン時に使用された **PFServiceConfigHandle** から取得されます。

```cpp theme={null}
// Get API endpoint
size_t endpointSize{};
HRESULT hr = PFEntityGetAPIEndpointSize(entityHandle, &endpointSize);

std::vector<char> endpoint(endpointSize);
hr = PFEntityGetAPIEndpoint(entityHandle, endpoint.size(), endpoint.data(), nullptr);

// Get title ID
size_t titleIdSize{};
hr = PFEntityGetTitleIdSize(entityHandle, &titleIdSize);

std::vector<char> titleId(titleIdSize);
hr = PFEntityGetTitleId(entityHandle, titleId.size(), titleId.data(), nullptr);
```

## 完全な例

この例では、エンティティハンドルの作成、複製、クエリ、およびクローズを示します:

```cpp theme={null}
#include <playfab/core/PFEntity.h>
#include <playfab/services/PFServices.h>

void EntityHandleExample(PFServiceConfigHandle serviceConfigHandle, XUserHandle userHandle)
{
    //
    // Log in and get an entity handle
    //
    PFAuthenticationLoginWithXUserRequest request{};
    request.createAccount = true;
    request.user = userHandle;

    XAsyncBlock asyncLogin{};
    HRESULT hr = PFAuthenticationLoginWithXUserAsync(serviceConfigHandle, &request, &asyncLogin);
    hr = XAsyncGetStatus(&asyncLogin, true);

    PFEntityHandle entityHandle{ nullptr };
    size_t resultSize{};
    hr = PFAuthenticationLoginWithXUserGetResultSize(&asyncLogin, &resultSize);

    std::vector<char> loginBuffer(resultSize);
    PFAuthenticationLoginResult const* loginResult{};
    hr = PFAuthenticationLoginWithXUserGetResult(
        &asyncLogin, &entityHandle,
        loginBuffer.size(), loginBuffer.data(),
        &loginResult, nullptr);

    //
    // Register token event handlers
    //
    PFRegistrationToken expiredToken{};
    hr = PFEntityRegisterTokenExpiredEventHandler(nullptr, nullptr,
        [](void* ctx, PFEntityKey const* entityKey)
        {
            // Handle re-authentication
        }, &expiredToken);

    PFRegistrationToken refreshedToken{};
    hr = PFEntityRegisterTokenRefreshedEventHandler(nullptr, nullptr,
        [](void* ctx, PFEntityKey const* entityKey, const PFEntityToken* newToken)
        {
            // Log token refresh
        }, &refreshedToken);

    //
    // Duplicate the handle for a subsystem
    //
    PFEntityHandle subsystemHandle{ nullptr };
    hr = PFEntityDuplicateHandle(entityHandle, &subsystemHandle);

    //
    // Query entity info
    //
    bool isTitlePlayer{};
    hr = PFEntityIsTitlePlayer(entityHandle, &isTitlePlayer);

    size_t keySize{};
    hr = PFEntityGetEntityKeySize(entityHandle, &keySize);

    std::vector<char> keyBuffer(keySize);
    PFEntityKey const* entityKey{};
    hr = PFEntityGetEntityKey(entityHandle, keyBuffer.size(), keyBuffer.data(), &entityKey, nullptr);

    //
    // ... make service calls with entityHandle or subsystemHandle ...
    //

    //
    // Cleanup: unregister handlers, then close all handles
    //
    PFEntityUnregisterTokenExpiredEventHandler(expiredToken);
    PFEntityUnregisterTokenRefreshedEventHandler(refreshedToken);

    PFEntityCloseHandle(subsystemHandle);
    PFEntityCloseHandle(entityHandle);
}
```

## API リファレンス

| 関数                                                                                                                                                 | 説明                                                       |
| -------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| [PFEntityDuplicateHandle](/services/playfab/api-references/c/pfentity/functions/pfentityduplicatehandle)                                           | 参照カウントをインクリメントしてハンドルを複製します。両方のハンドルは独立して閉じる必要があります。       |
| [PFEntityCloseHandle](/services/playfab/api-references/c/pfentity/functions/pfentityclosehandle)                                                   | ハンドルを閉じ、参照カウントをデクリメントします。最後のハンドルが閉じられたときにエンティティが破棄されます。  |
| [PFEntityGetEntityKeySize](/services/playfab/api-references/c/pfentity/functions/pfentitygetentitykeysize)                                         | エンティティキーを格納するために必要なバッファサイズを取得します。                        |
| [PFEntityGetEntityKey](/services/playfab/api-references/c/pfentity/functions/pfentitygetentitykey)                                                 | エンティティのエンティティキー (タイプと ID) を取得します。                        |
| [PFEntityGetEntityTokenAsync](/services/playfab/api-references/c/pfentity/functions/pfentitygetentitytokenasync)                                   | キャッシュされたエンティティトークンを非同期に取得します。                            |
| [PFEntityGetEntityTokenResultSize](/services/playfab/api-references/c/pfentity/functions/pfentitygetentitytokenresultsize)                         | エンティティトークン結果に必要なバッファサイズを取得します。                           |
| [PFEntityGetEntityTokenResult](/services/playfab/api-references/c/pfentity/functions/pfentitygetentitytokenresult)                                 | 完了した PFEntityGetEntityTokenAsync 呼び出しからエンティティトークンを取得します。 |
| [PFEntityIsTitlePlayer](/services/playfab/api-references/c/pfentity/functions/pfentityistitleplayer)                                               | エンティティが title\_player\_account かどうかを返します。                |
| [PFEntityGetSecretKeySize](/services/playfab/api-references/c/pfentity/functions/pfentitygetsecretkeysize)                                         | シークレットキーに必要なバッファサイズを取得します。エンティティがタイトルエンティティでない場合は失敗します。  |
| [PFEntityGetSecretKey](/services/playfab/api-references/c/pfentity/functions/pfentitygetsecretkey)                                                 | タイトルエンティティのシークレットキーを取得します。Windows、Linux、macOS でのみ利用可能です。 |
| [PFEntityGetAPIEndpointSize](/services/playfab/api-references/c/pfentity/functions/pfentitygetapiendpointsize)                                     | API エンドポイント文字列に必要なバッファサイズを取得します。                         |
| [PFEntityGetAPIEndpoint](/services/playfab/api-references/c/pfentity/functions/pfentitygetapiendpoint)                                             | エンティティに関連付けられたサービス設定から API エンドポイントを取得します。                |
| **PFEntityGetTitleIdSize**                                                                                                                         | タイトル ID 文字列に必要なバッファサイズを取得します。                            |
| **PFEntityGetTitleId**                                                                                                                             | エンティティに関連付けられたサービス設定からタイトル ID を取得します。                    |
| [PFEntityRegisterTokenExpiredEventHandler](/services/playfab/api-references/c/pfentity/functions/pfentityregistertokenexpiredeventhandler)         | 自動トークン更新が失敗したときのコールバックを登録します。                            |
| [PFEntityUnregisterTokenExpiredEventHandler](/services/playfab/api-references/c/pfentity/functions/pfentityunregistertokenexpiredeventhandler)     | トークン期限切れコールバックを登録解除します。                                  |
| [PFEntityRegisterTokenRefreshedEventHandler](/services/playfab/api-references/c/pfentity/functions/pfentityregistertokenrefreshedeventhandler)     | SDK がトークンを正常に更新したときのコールバックを登録します。                        |
| [PFEntityUnregisterTokenRefreshedEventHandler](/services/playfab/api-references/c/pfentity/functions/pfentityunregistertokenrefreshedeventhandler) | トークン更新コールバックを登録解除します。                                    |

完全な API リファレンスについては、[PFEntity メンバー](/services/playfab/api-references/c/pfentity/pfentity_members) を参照してください。

## 関連項目

* [トークン期限切れの処理](/services/playfab/sdks/c/relogin)
* [タイトルエンティティで PlayFab にアクセスする](/services/playfab/sdks/c/server)
* [SDK ライフサイクル](/services/playfab/sdks/c/lifecycle)
* [クイックスタート: Windows](/services/playfab/sdks/c/quickstart-gdk)
* [クイックスタート: Win32](/services/playfab/sdks/c/quickstart-win32)


## Related topics

- [クイックスタート (Windows) - PlayFab サービスの呼び出し](/ja-jp/services/playfab/sdks/unified-sdk/quickstart-services.md)
- [イベントパイプラインチュートリアル](/ja-jp/services/playfab/sdks/c/event-pipeline/eventpipeline-tutorial.md)
- [PlayFab Services SDK - イベントパイプライン](/ja-jp/services/playfab/sdks/c/event-pipeline/eventpipeline.md)
- [クイックスタート (Windows) - Party とマルチプレイヤー](/ja-jp/services/playfab/sdks/unified-sdk/quickstart-windows-party.md)
- [タイトル エンティティからのゲーム サーバー](/ja-jp/services/playfab/sdks/c/server.md)
