> ## Documentation Index
> Fetch the complete documentation index at: https://docs.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**](https://docs.xbox.com/es/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions.md) 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);
```

> [!NOTE]
>
> Se debe llamar a [**PFMemSetFunctions**](https://docs.xbox.com/es/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions.md) antes que a [**PFInitialize**](https://docs.xbox.com/es/services/playfab/api-references/c/pfcore/functions/pfinitialize.md). No se puede volver a llamar después de que los enlaces se hayan establecido.

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**](https://docs.xbox.com/es/services/playfab/api-references/c/pfcore/functions/pfinitialize.md) 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**](https://docs.xbox.com/es/services/playfab/api-references/c/pfservices/functions/pfservicesinitialize.md) 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**](https://docs.xbox.com/es/services/playfab/api-references/c/pfservices/functions/pfservicesinitialize.md) inicializa Core antes de que los enlaces de memoria surtan efecto y el SDK usa las rutinas de asignación predeterminadas en su lugar.

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

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

### Duplicación de un identificador

Use [**PFServiceConfigDuplicateHandle**](https://docs.xbox.com/es/services/playfab/api-references/c/pfserviceconfig/functions/pfserviceconfigduplicatehandle.md) 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**](https://docs.xbox.com/es/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync.md) 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**](https://docs.xbox.com/es/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync.md) 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**](https://docs.xbox.com/es/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync.md) gestiona automáticamente la limpieza de Core. Sin embargo, si llamó a **PFInitialize** usted mismo, debe llamar a [**PFUninitializeAsync**](https://docs.xbox.com/es/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync.md) usted mismo.

## 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**](https://docs.xbox.com/es/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions.md) después de [**PFInitialize**](https://docs.xbox.com/es/services/playfab/api-references/c/pfcore/functions/pfinitialize.md) | La llamada produce un error. Los enlaces de memoria solo pueden establecerse antes de la inicialización. | Mueva [**PFMemSetFunctions**](https://docs.xbox.com/es/services/playfab/api-references/c/pfplatform/functions/pfmemsetfunctions.md) para que sea la primera llamada de PlayFab de su programa. |
| Llamar a [**PFUninitializeAsync**](https://docs.xbox.com/es/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync.md) antes de [**PFServicesUninitializeAsync**](https://docs.xbox.com/es/services/playfab/api-references/c/pfservices/functions/pfservicesuninitializeasync.md) | 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**](https://docs.xbox.com/es/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync.md) después de un [**PFInitialize**](https://docs.xbox.com/es/services/playfab/api-references/c/pfcore/functions/pfinitialize.md) explícito | Se pierden recursos de Core. La cola en segundo plano y la capa HTTP no se limpian. | Si llamó a [**PFInitialize**](https://docs.xbox.com/es/services/playfab/api-references/c/pfcore/functions/pfinitialize.md), debe llamar a [**PFUninitializeAsync**](https://docs.xbox.com/es/services/playfab/api-references/c/pfcore/functions/pfuninitializeasync.md). |
| 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](https://docs.xbox.com/es/services/playfab/sdks/c/quickstart-win32.md)
* [Inicio rápido: Windows](https://docs.xbox.com/es/services/playfab/sdks/c/quickstart-gdk.md)
* [Seguimiento de depuración](https://docs.xbox.com/es/services/playfab/sdks/c/tracing.md)
* [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](https://docs.xbox.com/es/services/playfab/sdks/c/entity-handles.md)
- [Ciclo de vida de un servidor multijugador](https://docs.xbox.com/es/services/playfab/multiplayer/servers/multiplayer-game-server-lifecycle.md)
- [Ciclo de vida de las compilaciones de servidores multijugador](https://docs.xbox.com/es/services/playfab/multiplayer/servers/multiplayer-build-lifecycle.md)
- [Ciclo de vida de una región de compilación de servidor multijugador](https://docs.xbox.com/es/services/playfab/multiplayer/servers/multiplayer-build-region-lifecycle.md)
- [SDK de PlayFab Services: canalización de eventos](https://docs.xbox.com/es/services/playfab/sdks/c/event-pipeline/eventpipeline.md)
