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

# Ciclo de vida del SDK

> Inicialice, configure y cierre el SDK de C de PlayFab Services en el orden correcto, incluidos los enlaces de memoria, Core y la configuración de servicio.

Esta página describe la secuencia completa de inicio y cierre del SDK de PlayFab Services. Todos los títulos siguen el mismo patrón general: configurar los enlaces opcionales, inicializar Core, crear una configuración de servicio, inicializar Services, realizar el trabajo y, después, cerrar en orden inverso.

## Secuencia de inicialización

La inicialización tiene cuatro pasos. El primero es opcional; los tres restantes son obligatorios.

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

### Paso 1: Establecer enlaces de memoria personalizados (opcional)

Si su título usa un asignador de memoria personalizado, llame a [**PFMemSetFunctions**](/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions) antes que a cualquier otra API de PlayFab. Esto enruta todas las asignaciones de memoria del SDK a través de sus propias devoluciones de llamada `alloc` y `free`.

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

<Info>
  Se debe llamar a [**PFMemSetFunctions**](/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions) antes que a [**PFInitialize**](/services/playfab/api-references/c/pfcore/functions/pfinitialize). No se puede volver a llamar después de que los enlaces se hayan establecido.
</Info>

Si no necesita administración de memoria personalizada, omita este paso. El SDK usa las rutinas de asignación predeterminadas.

### Paso 2: Inicializar PlayFab Core

[**PFInitialize**](/services/playfab/api-references/c/pfcore/functions/pfinitialize) configura el estado global del SDK, incluida la capa HTTP y la cola de tareas en segundo plano. La firma exacta varía según la plataforma.

#### Windows, Linux, iOS y macOS

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

Pase un **XTaskQueueHandle** si quiere controlar qué cola gestiona el trabajo en segundo plano. Pase `nullptr` para usar la cola de grupo de subprocesos predeterminada.

#### Android

En Android, también debe proporcionar la máquina virtual de Java y el contexto de la aplicación para que el SDK pueda inicializar libHttpClient:

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

<Note>
  Si no llama a **PFInitialize** explícitamente, [**PFServicesInitialize**](/services/playfab/api-references/c/pfservices/functions/pfservicesinitialize) lo llama internamente con parámetros predeterminados. Esto es adecuado para la mayoría de los títulos. Sin embargo, si usa enlaces de memoria personalizados a través de **PFMemSetFunctions**, **debe** llamar a **PFInitialize** usted mismo; de lo contrario, [**PFServicesInitialize**](/services/playfab/api-references/c/pfservices/functions/pfservicesinitialize) inicializa Core antes de que los enlaces de memoria surtan efecto y el SDK usa las rutinas de asignación predeterminadas en su lugar.
</Note>

### Paso 3: Crear una configuración de servicio

[**PFServiceConfigCreateHandle**](/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigcreatehandle) crea un identificador que indica al SDK a qué título y punto de conexión de PlayFab dirigirse. Encontrará ambos valores en [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);
```

El **PFServiceConfigHandle** devuelto es necesario para todas las llamadas de inicio de sesión posteriores.

### Paso 4: Inicializar PlayFab Services

**PFServicesInitialize** configura la capa de Services (Inventory, Leaderboards, Friends, etc.) sobre Core.

#### Windows, Linux, iOS y macOS

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

El parámetro está reservado para uso futuro; pase `nullptr`.

#### Android

En Android, pase una estructura **HCInitArgs** que contenga la máquina virtual de Java y el contexto de la aplicación:

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

Cuando esta llamada se complete correctamente, el SDK estará listo. Puede iniciar la sesión de los jugadores y realizar llamadas al servicio.

## Ciclo de vida de PFServiceConfigHandle

Un **PFServiceConfigHandle** es un identificador con recuento de referencias. El SDK administra su duración interna mediante el recuento de referencias, pero usted es responsable de cerrar cada identificador que posea.

| Función                                                                                                                           | Descripción                                                                                                                                                                                                                                      |
| --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [**PFServiceConfigCreateHandle**](/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigcreatehandle)       | Crea un identificador nuevo. El recuento de referencias inicial es 1.                                                                                                                                                                            |
| [**PFServiceConfigDuplicateHandle**](/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigduplicatehandle) | Incrementa el recuento de referencias y devuelve un segundo identificador. Ambos identificadores deben cerrarse de forma independiente.                                                                                                          |
| [**PFServiceConfigCloseHandle**](/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigclosehandle)         | Disminuye el recuento de referencias. Cuando llega a 0, la configuración se destruye.                                                                                                                                                            |
| [**PFServiceConfigGetAPIEndpoint**](/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfiggetapiendpoint)   | Recupera la cadena del punto de conexión de la API. Llame primero a [**PFServiceConfigGetAPIEndpointSize**](/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfiggetapiendpointsize) para determinar el tamaño del búfer. |
| [**PFServiceConfigGetTitleId**](/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfiggettitleid)           | Recupera la cadena del identificador del título. Llame primero a [**PFServiceConfigGetTitleIdSize**](/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfiggettitleidsize) para determinar el tamaño del búfer.            |

### Duplicación de un identificador

Use [**PFServiceConfigDuplicateHandle**](/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigduplicatehandle) cuando necesite compartir una configuración de servicio entre componentes que administran sus propias duraciones:

```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);
```

## Secuencia de cierre

El cierre es el inverso de la inicialización. Debe desinicializar Services antes que Core, y ambas llamadas son asincrónicas.

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

### Paso 1: Cerrar todos los identificadores abiertos

Antes de desmontar el SDK, cierre cada **PFEntityHandle** y **PFServiceConfigHandle** que posea:

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

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

### Paso 2: Desinicializar Services

[**PFServicesUninitializeAsync**](/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync) desmonta la capa de Services. Espere a que se complete antes de continuar.

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

### Paso 3: Desinicializar Core

Una vez finalizada la limpieza de Services, llame a [**PFUninitializeAsync**](/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync) para desmontar Core:

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

<Note>
  Si no llamó a **PFInitialize** explícitamente, puede omitir **PFUninitializeAsync**. En ese caso, [**PFServicesUninitializeAsync**](/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync) gestiona automáticamente la limpieza de Core. Sin embargo, si llamó a **PFInitialize** usted mismo, debe llamar a [**PFUninitializeAsync**](/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync) usted mismo.
</Note>

## Ejemplo completo

En este ejemplo se muestra el ciclo de vida completo desde la inicialización hasta el cierre en un título de 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);
}
```

## Errores comunes

| Error                                                                                                                                                                                                                                       | Qué ocurre                                                                                                     | Solución                                                                                                                                                                                                           |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Llamar a [**PFMemSetFunctions**](/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions) después de [**PFInitialize**](/services/playfab/api-references/c/pfcore/functions/pfinitialize)                                 | La llamada produce un error. Los enlaces de memoria solo pueden establecerse antes de la inicialización.       | Mueva [**PFMemSetFunctions**](/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions) para que sea la primera llamada de PlayFab de su programa.                                                |
| Llamar a [**PFUninitializeAsync**](/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync) antes de [**PFServicesUninitializeAsync**](/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync) | Comportamiento indefinido. Core se desmonta mientras Services todavía depende de él.                           | Desinicialice siempre Services primero, espere a que se complete y, después, desinicialice Core.                                                                                                                   |
| Olvidar llamar a [**PFUninitializeAsync**](/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync) después de un [**PFInitialize**](/services/playfab/api-references/c/pfcore/functions/pfinitialize) explícito            | Se pierden recursos de Core. La cola en segundo plano y la capa HTTP no se limpian.                            | Si llamó a [**PFInitialize**](/services/playfab/api-references/c/pfcore/functions/pfinitialize), debe llamar a [**PFUninitializeAsync**](/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync). |
| No esperar a que se complete la desinicialización asincrónica                                                                                                                                                                               | El proceso puede finalizar mientras la limpieza sigue en curso, lo que provoca bloqueos o cierres inesperados. | Use `XAsyncGetStatus(async, true)` o una devolución de llamada de **XAsyncBlock** para esperar a la finalización.                                                                                                  |
| Perder identificadores **PFServiceConfigHandle** o **PFEntityHandle**                                                                                                                                                                       | Los recursos con recuento de referencias no se liberan y pueden impedir un cierre limpio.                      | Cierre todos los identificadores que cree o duplique antes de llamar a la desinicialización.                                                                                                                       |

## Consulte también

* [Inicio rápido: Win32](/services/playfab/sdks/c/quickstart-win32)
* [Inicio rápido: Windows](/services/playfab/sdks/c/quickstart-gdk)
* [Seguimiento de depuración](/services/playfab/sdks/c/tracing)
* [Modelo de programación asincrónica](https://learn.microsoft.com/en-us/gaming/gdk/_content/gc/system/overviews/async-programming-model)


## Related topics

- [Identificadores de entidad](/es/services/playfab/sdks/c/entity-handles.md)
- [Ciclo de vida de un servidor multijugador](/es/services/playfab/multiplayer/servers/multiplayer-game-server-lifecycle.md)
- [Ciclo de vida de una región de compilación de servidor multijugador](/es/services/playfab/multiplayer/servers/multiplayer-build-region-lifecycle.md)
- [Ciclo de vida de las compilaciones de servidores multijugador](/es/services/playfab/multiplayer/servers/multiplayer-build-lifecycle.md)
- [Notas de la versión del SDK de C++ de PlayFab Multiplayer](/es/services/playfab/multiplayer/lobby/lobby-matchmaking-sdks/lobby-and-matchmaking-release-notes.md)
