> ## 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.

# Cycle de vie du SDK

> Initialisez, configurez et arrêtez le SDK C PlayFab Services dans le bon ordre, y compris les hooks de mémoire, Core et la configuration du service.

Cette page décrit la séquence complète de démarrage et d'arrêt du SDK PlayFab Services. Tous les titres suivent le même modèle général : configurer les hooks facultatifs, initialiser Core, créer une configuration de service, initialiser Services, effectuer le travail, puis tout arrêter dans l'ordre inverse.

## Séquence d'initialisation

L'initialisation comporte quatre étapes. La première est facultative; les trois autres sont obligatoires.

```
PFMemSetFunctions (optional)  →  PFInitialize  →  PFServiceConfigCreateHandle  →  PFServicesInitialize
```

### Étape 1 : définir des hooks de mémoire personnalisés (facultatif)

Si votre titre utilise un allocateur de mémoire personnalisé, appelez [**PFMemSetFunctions**](/fr-CA/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions) avant toute autre API PlayFab. Toutes les allocations de mémoire du SDK passent alors par vos propres rappels `alloc` et `free`.

```cpp theme={null}
PFMemoryHooks hooks{};
hooks.alloc = MyAllocFunction;
hooks.free = MyFreeFunction;
HRESULT hr = PFMemSetFunctions(&hooks);
```

<Info>
  [**PFMemSetFunctions**](/fr-CA/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions) doit être appelé avant [**PFInitialize**](/fr-CA/services/playfab/api-references/c/pfcore/functions/pfinitialize). Il ne peut pas être appelé à nouveau une fois les hooks définis.
</Info>

Si vous n'avez pas besoin d'une gestion personnalisée de la mémoire, ignorez cette étape. Le SDK utilise les routines d'allocation par défaut.

### Étape 2 : initialiser PlayFab Core

[**PFInitialize**](/fr-CA/services/playfab/api-references/c/pfcore/functions/pfinitialize) configure l'état global du SDK, notamment la couche HTTP et la file d'attente des tâches d'arrière-plan. La signature exacte varie selon la plateforme.

#### Windows, Linux, iOS et macOS

```cpp theme={null}
HRESULT hr = PFInitialize(nullptr); // Uses a default threadpool queue
```

Transmettez un **XTaskQueueHandle** si vous souhaitez contrôler la file d'attente qui gère le travail en arrière-plan. Transmettez `nullptr` pour utiliser la file d'attente du pool de threads par défaut.

#### Android

Sur Android, vous devez également fournir la machine virtuelle Java et le contexte de l'application afin que le SDK puisse initialiser libHttpClient :

```cpp theme={null}
HRESULT hr = PFInitialize(nullptr, javaVm, applicationContext);
```

<Note>
  Si vous n'appelez pas explicitement **PFInitialize**, [**PFServicesInitialize**](/fr-CA/services/playfab/api-references/c/pfservices/functions/pfservicesinitialize) l'appelle en interne avec les paramètres par défaut. Cela convient à la plupart des titres. Toutefois, si vous utilisez des hooks de mémoire personnalisés au moyen de **PFMemSetFunctions**, vous **devez** appeler vous-même **PFInitialize**; sinon, [**PFServicesInitialize**](/fr-CA/services/playfab/api-references/c/pfservices/functions/pfservicesinitialize) initialise Core avant que vos hooks de mémoire ne prennent effet, et le SDK utilise alors les routines d'allocation par défaut.
</Note>

### Étape 3 : créer une configuration de service

[**PFServiceConfigCreateHandle**](/fr-CA/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigcreatehandle) crée un handle qui indique au SDK le titre et le point de terminaison PlayFab à cibler. Vous trouverez ces deux valeurs dans [Game Manager](https://developer.playfab.com).

```cpp theme={null}
PFServiceConfigHandle serviceConfigHandle{ nullptr };
HRESULT hr = PFServiceConfigCreateHandle(
    "https://ABCDEF.playfabapi.com",    // API endpoint from Game Manager
    "ABCDEF",                           // Title ID from Game Manager
    &serviceConfigHandle);
```

Le **PFServiceConfigHandle** retourné est requis pour tous les appels de connexion ultérieurs.

### Étape 4 : initialiser PlayFab Services

**PFServicesInitialize** configure la couche Services (Inventory, Leaderboards, Friends, etc.) au-dessus de Core.

#### Windows, Linux, iOS et macOS

```cpp theme={null}
HRESULT hr = PFServicesInitialize(nullptr);
```

Le paramètre est réservé à un usage ultérieur; transmettez `nullptr`.

#### Android

Sur Android, transmettez un struct **HCInitArgs** contenant la machine virtuelle Java et le contexte de l'application :

```cpp theme={null}
HRESULT hr = PFServicesInitialize(nullptr, initArgs);
```

Une fois cet appel réussi, le SDK est prêt. Vous pouvez connecter des joueurs et effectuer des appels de service.

## Cycle de vie de PFServiceConfigHandle

Un **PFServiceConfigHandle** est un handle à comptage de références. Le SDK gère sa durée de vie interne par comptage de références, mais il vous incombe de fermer chaque handle que vous possédez.

| Fonction | Description |
| - | - |
| [**PFServiceConfigCreateHandle**](/fr-CA/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigcreatehandle) | Crée un nouveau handle. Le compteur de références initial est 1. |
| [**PFServiceConfigDuplicateHandle**](/fr-CA/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigduplicatehandle) | Incrémente le compteur de références et retourne un deuxième handle. Les deux handles doivent être fermés indépendamment. |
| [**PFServiceConfigCloseHandle**](/fr-CA/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigclosehandle) | Décrémente le compteur de références. Lorsqu'il atteint 0, la configuration est détruite. |
| [**PFServiceConfigGetAPIEndpoint**](/fr-CA/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfiggetapiendpoint) | Récupère la chaîne du point de terminaison de l'API. Appelez d'abord [**PFServiceConfigGetAPIEndpointSize**](/fr-CA/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfiggetapiendpointsize) pour déterminer la taille de la mémoire tampon. |
| [**PFServiceConfigGetTitleId**](/fr-CA/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfiggettitleid) | Récupère la chaîne de l'ID du titre. Appelez d'abord [**PFServiceConfigGetTitleIdSize**](/fr-CA/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfiggettitleidsize) pour déterminer la taille de la mémoire tampon. |

### Dupliquer un handle

Utilisez [**PFServiceConfigDuplicateHandle**](/fr-CA/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigduplicatehandle) lorsque vous devez partager une configuration de service entre des composants qui gèrent leur propre durée de vie :

```cpp theme={null}
PFServiceConfigHandle duplicatedHandle{ nullptr };
HRESULT hr = PFServiceConfigDuplicateHandle(serviceConfigHandle, &duplicatedHandle);

// Both handles are now valid and must be closed separately
PFServiceConfigCloseHandle(duplicatedHandle);
PFServiceConfigCloseHandle(serviceConfigHandle);
```

## Séquence d'arrêt

L'arrêt suit l'ordre inverse de l'initialisation. Vous devez désinitialiser Services avant Core, et les deux appels sont asynchrones.

```
Close handles  →  PFServicesUninitializeAsync  →  PFUninitializeAsync
```

### Étape 1 : fermer tous les handles ouverts

Avant de démonter le SDK, fermez chaque **PFEntityHandle** et **PFServiceConfigHandle** que vous possédez :

```cpp theme={null}
PFEntityCloseHandle(entityHandle);
entityHandle = nullptr;

PFServiceConfigCloseHandle(serviceConfigHandle);
serviceConfigHandle = nullptr;
```

### Étape 2 : désinitialiser Services

[**PFServicesUninitializeAsync**](/fr-CA/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync) démonte la couche Services. Attendez la fin de cette opération avant de continuer.

```cpp theme={null}
XAsyncBlock asyncServices{};
HRESULT hr = PFServicesUninitializeAsync(&asyncServices);
hr = XAsyncGetStatus(&asyncServices, true); // Blocking wait
```

### Étape 3 : désinitialiser Core

Une fois le nettoyage de Services terminé, appelez [**PFUninitializeAsync**](/fr-CA/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync) pour démonter Core :

```cpp theme={null}
XAsyncBlock asyncCore{};
HRESULT hr = PFUninitializeAsync(&asyncCore);
hr = XAsyncGetStatus(&asyncCore, true); // Blocking wait
```

<Note>
  Si vous n'avez pas appelé explicitement **PFInitialize**, vous pouvez ignorer **PFUninitializeAsync**. Dans ce cas, [**PFServicesUninitializeAsync**](/fr-CA/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync) gère automatiquement le nettoyage de Core. Toutefois, si vous avez appelé vous-même **PFInitialize**, vous devez appeler vous-même [**PFUninitializeAsync**](/fr-CA/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync).
</Note>

## Exemple complet

Cet exemple montre le cycle de vie complet, de l'initialisation à l'arrêt, pour un titre Windows :

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

void RunPlayFab()
{
    //
    // Optional: set custom memory hooks
    //
    PFMemoryHooks hooks{};
    hooks.alloc = MyAllocFunction;
    hooks.free = MyFreeFunction;
    HRESULT hr = PFMemSetFunctions(&hooks);

    //
    // Initialize Core
    //
    hr = PFInitialize(nullptr);

    //
    // Create a service configuration
    //
    PFServiceConfigHandle serviceConfigHandle{ nullptr };
    hr = PFServiceConfigCreateHandle(
        "https://ABCDEF.playfabapi.com",
        "ABCDEF",
        &serviceConfigHandle);

    //
    // Initialize Services
    //
    hr = PFServicesInitialize(nullptr);

    //
    // Log in a player (Windows example using XUser)
    //
    PFAuthenticationLoginWithXUserRequest request{};
    request.createAccount = true;
    request.user = userHandle;

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

    size_t bufferSize{};
    hr = PFAuthenticationLoginWithXUserGetResultSize(&asyncLogin, &bufferSize);

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

    //
    // ... make service calls ...
    //

    //
    // Shutdown: close handles first
    //
    PFEntityCloseHandle(entityHandle);
    entityHandle = nullptr;

    PFServiceConfigCloseHandle(serviceConfigHandle);
    serviceConfigHandle = nullptr;

    //
    // Shutdown: uninitialize Services, then Core
    //
    XAsyncBlock asyncServices{};
    hr = PFServicesUninitializeAsync(&asyncServices);
    hr = XAsyncGetStatus(&asyncServices, true);

    XAsyncBlock asyncCore{};
    hr = PFUninitializeAsync(&asyncCore);
    hr = XAsyncGetStatus(&asyncCore, true);
}
```

## Erreurs courantes

| Erreur | Conséquence | Correction |
| - | - | - |
| Appeler [**PFMemSetFunctions**](/fr-CA/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions) après [**PFInitialize**](/fr-CA/services/playfab/api-references/c/pfcore/functions/pfinitialize) | L'appel échoue. Les hooks de mémoire ne peuvent être définis qu'avant l'initialisation. | Faites de [**PFMemSetFunctions**](/fr-CA/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions) le tout premier appel PlayFab de votre programme. |
| Appeler [**PFUninitializeAsync**](/fr-CA/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync) avant [**PFServicesUninitializeAsync**](/fr-CA/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync) | Comportement non défini. Core est démonté alors que Services en dépend encore. | Désinitialisez toujours Services en premier, attendez la fin de l'opération, puis désinitialisez Core. |
| Oublier d'appeler [**PFUninitializeAsync**](/fr-CA/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync) après un appel explicite à [**PFInitialize**](/fr-CA/services/playfab/api-references/c/pfcore/functions/pfinitialize) | Fuite des ressources de Core. La file d'attente d'arrière-plan et la couche HTTP ne sont pas nettoyées. | Si vous avez appelé [**PFInitialize**](/fr-CA/services/playfab/api-references/c/pfcore/functions/pfinitialize), vous devez appeler [**PFUninitializeAsync**](/fr-CA/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync). |
| Ne pas attendre la fin de la désinitialisation asynchrone | Le processus peut se terminer alors que le nettoyage est toujours en cours, provoquant des plantages ou des blocages. | Utilisez `XAsyncGetStatus(async, true)` ou un rappel **XAsyncBlock** pour attendre la fin de l'opération. |
| Fuite de **PFServiceConfigHandle** ou de **PFEntityHandle** | Les ressources à comptage de références ne sont pas libérées et peuvent empêcher un arrêt propre. | Fermez chaque handle que vous créez ou dupliquez avant d'appeler la désinitialisation. |

## Voir aussi

* [Démarrage rapide : Win32](/fr-CA/services/playfab/sdks/c/quickstart-win32)
* [Démarrage rapide : Windows](/fr-CA/services/playfab/sdks/c/quickstart-gdk)
* [Traçage de débogage](/fr-CA/services/playfab/sdks/c/tracing)
* [Modèle de programmation asynchrone](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/system/overviews/async-programming-model)


## Related topics

- [Cycle de vie d'un serveur multijoueur](/fr-CA/services/playfab/multiplayer/servers/multiplayer-game-server-lifecycle.md)
- [Handles d'entité](/fr-CA/services/playfab/sdks/c/entity-handles.md)
- [Notes de version du SDK C++ PlayFab Multiplayer](/fr-CA/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/lobby-and-matchmaking-release-notes.md)
- [Cycle de vie d'une région de build de serveur multijoueur](/fr-CA/services/playfab/multiplayer/servers/multiplayer-build-region-lifecycle.md)
- [Cycle de vie des builds de serveur multijoueur](/fr-CA/services/playfab/multiplayer/servers/multiplayer-build-lifecycle.md)
