Skip to main content

C++ SDK Quick Integration

WebGLHost C++ SDK provides standard C++ interfaces for integrating and managing WebGL game applets in Windows and macOS desktop applications.

1. Obtain Credentials​

Integrating the SDK requires first creating an application in the minigame host Console, obtaining the APP KEY, APP SECRET, and Service Token specific to each application.

When starting the SDK, initialization is required through APP KEY, APP SECRET. The accessing party can also contact Unity to create App Service Token / App Key / App Secret.

The following is an example of test App Service Token / App Key / App Secret:

  • App Service Token
  • App Key: AKIDt1vMSYVFf1twI53iDecobx6QsTK0
  • App Secret: ufzN1iD8PsnMW0ViDCMhpJFBiLR1E1Xf

Service Token is mainly used to call the following API to obtain the game list, from which Game ID and Launch Key can be retrieved to start the game.

Use a token to obtain a list of minigames

1.1 Key ID Description​

When integrating the SDK, you need to understand the following key identifiers:

IdentifierDescriptionSource
Game ID (Applet ID)Unique identifier of the game, used for the first parameter of LaunchApplet and CloseAppletid field returned by Game List API
Launch KeyGame launch key, used for launchKey field in launchConfiglaunchKey field returned by Game List API
Host App IDUnique identifier of the host application, used to get the game listObtained when creating an application in the console
Access TokenUser access token, used for authenticationProvided by the host application's user system

Game List API Response Example:

[
{
"id": "691acb162dcfadc65a0fdb77", // Game ID - for LaunchApplet first parameter
"appId": "691ac9ef2dcfadc65a0fb4a6", // Host App ID
"name": "Example Game",
"launchKey": "691acb162dcfadc65a0fdb77", // Launch Key - for launchConfig
"gameType": "webgl",
"briefIntro": "This is an example game"
}
]

In a real production environment, Service Token should be used on the server side, and the above API should be called from the server. In the Demo project, Service Token is used on the client side, which is just an example and not recommended for use in a production environment.

2. Get SDK​

2.1 Download SDK​

Download the latest C++ SDK package from the PC SDK Download Page.

2.2 Get Demo Project​

The complete C++ SDK Demo project can be obtained from GitHub:

GitHub Repository: https://github.com/UnityMiniHost/PCDemo

# Clone Demo project
git clone https://github.com/UnityMiniHost/PCDemo.git
cd PCDemo

SDK Demo project contains the following:

PCDemo_cpp/
├── include/ # SDK header files
│ ├── IBrowsingService.h # Main service interface
│ ├── IAppletManagerV3.h # Game management interface
│ ├── ICoreServiceHandler.h # Event handler interface
│ └── WIUnknown.h # Base interface
├── native_sdk/ # Pre-packaged SDK and runtime
│ ├── windows/ # Windows platform
│ │ ├── host.zip # SDK DLL (webglhost_export.dll)
│ │ ├── runtime.z01 # Runtime split archive (part 1)
│ │ ├── runtime.z02 # Runtime split archive (part 2)
│ │ ├── runtime.z03 # Runtime split archive (part 3)
│ │ └── version.json # Version info
│ └── mac/ # macOS platform
│ ├── runtime-x64.tar.gz.01 # x64 runtime split archive (part 1)
│ ├── runtime-x64.tar.gz.02 # x64 runtime split archive (part 2)
│ ├── runtime-x64.tar.gz.03 # x64 runtime split archive (part 3)
│ ├── runtime-arm64.tar.gz.01 # ARM64 runtime split archive (part 1)
│ ├── runtime-arm64.tar.gz.02 # ARM64 runtime split archive (part 2)
│ ├── runtime-arm64.tar.gz.03 # ARM64 runtime split archive (part 3)
│ └── version.json # Version info
├── demo.cpp # Sample code
├── CMakeLists.txt # CMake build configuration
├── scripts/ # Build and run scripts
│ ├── build.bat # Windows build script
│ ├── build.sh # macOS build script
│ ├── build-and-run.bat # Windows one-click build and run
│ ├── build-and-run.sh # macOS one-click build and run
│ ├── clean.bat # Windows clean script
│ ├── clean.sh # macOS clean script
│ ├── pack.bat # Windows pack script
│ ├── pack.sh # macOS pack script
│ ├── run.bat # Windows run script
│ ├── run.sh # macOS run script
│ └── USAGE.md # Script usage guide
├── docs/ # Documentation
│ ├── Quick-Start-Guide.md # Quick start guide
│ └── API-Integration-Guide.md # API integration guide
└── README.md # Project readme

**Notes**:
- SDK and runtime files are pre-packaged in the `native_sdk/` directory
- Split archives are used to accommodate Git repository size limits
- Build scripts will automatically extract these files to the correct location
- Windows: `webglhost_export.dll` and `webglhost-runtime.exe`
- macOS: `libwebglhost_export.dylib` and `webglhost-runtime.app`

3. Quick Start​

3.1 Add Header Files​

Add the include/ directory to your project's include path:

#include "IBrowsingService.h"
#include "IAppletManagerV3.h"
#include "ICoreServiceHandler.h"

3.2 Configure Project​

CMake Configuration:

# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Add header file path
include_directories(${CMAKE_SOURCE_DIR}/include)

# Link libraries (Windows)
if(WIN32)
target_link_libraries(your_app ws2_32)
endif()

Visual Studio Project Configuration (Windows):

  1. Project Properties → C/C++ → General → Additional Include Directories: Add include path
  2. Project Properties → Linker → Input → Additional Dependencies: Add ws2_32.lib
  3. Project Properties → C/C++ → Language → C++ Language Standard: ISO C++17 Standard

Xcode Project Configuration (macOS):

  1. Build Settings → Header Search Paths: Add include path
  2. Build Settings → C++ Language Dialect: C++17
  3. No additional libraries needed (system frameworks auto-linked)

3.3 Load SDK​

Windows:

#include <windows.h>
#include "IBrowsingService.h"

// Load DLL
HMODULE hDll = LoadLibraryA("host\\webglhost_export.dll");
if (!hDll) {
std::cerr << "Failed to load DLL" << std::endl;
return 1;
}

// Get factory function
typedef IBrowsingService* (*GetBrowsingServiceFunc)();
GetBrowsingServiceFunc GetBrowsingService =
(GetBrowsingServiceFunc)GetProcAddress(hDll, "GetBrowsingService");

if (!GetBrowsingService) {
std::cerr << "Failed to get GetBrowsingService function" << std::endl;
FreeLibrary(hDll);
return 1;
}

// Get service instance
IBrowsingService* service = GetBrowsingService();

macOS:

#include <dlfcn.h>
#include "IBrowsingService.h"

// Load dylib
void* hDll = dlopen("host/libwebglhost_export.dylib", RTLD_LAZY);
if (!hDll) {
std::cerr << "Failed to load dylib: " << dlerror() << std::endl;
return 1;
}

// Get factory function
typedef IBrowsingService* (*GetBrowsingServiceFunc)();
GetBrowsingServiceFunc GetBrowsingService =
(GetBrowsingServiceFunc)dlsym(hDll, "GetBrowsingService");

if (!GetBrowsingService) {
std::cerr << "Failed to get GetBrowsingService function: " << dlerror() << std::endl;
dlclose(hDll);
return 1;
}

// Get service instance
IBrowsingService* service = GetBrowsingService();

3.4 Initialize SDK​

// Configuration
const char* SDK_KEY = "your-sdk-key";
const char* SDK_SECRET = "your-sdk-secret";

// Build config JSON
char config[1024];
snprintf(config, sizeof(config), R"({
"sdkKey": "%s",
"sdkSecret": "%s",
"debug": true
})", SDK_KEY, SDK_SECRET);

// Initialize (runtime_path: empty for auto-detection)
int result = service->InitializeBrowsingCore(config, "", nullptr);

if (result == WMPF_ERRCODE_SUCCESS) {
std::cout << "SDK initialized successfully!" << std::endl;
} else {
std::cerr << "SDK initialization failed: " << result << std::endl;
return 1;
}

3.5 Get Game Manager​

// Query IAppletManagerV3 interface
IAppletManagerV3* appletMgr = nullptr;
result = service->QueryInterface("IAppletManagerV3", (void**)&appletMgr);

if (result != WMPF_ERRCODE_SUCCESS || !appletMgr) {
std::cerr << "Failed to get IAppletManagerV3" << std::endl;
return 1;
}

std::cout << "Got IAppletManagerV3 interface" << std::endl;

3.6 Launch Game​

// Launch callback
void OnLaunchComplete(const char* app_id, int result_code, const char* error_desc) {
if (result_code == WMPF_ERRCODE_SUCCESS) {
std::cout << "Game launched successfully: " << app_id << std::endl;
} else {
std::cerr << "Game launch failed: " << error_desc << std::endl;
}
}

// Game configuration
// APPLET_ID: from "id" field returned by Game List API
// LAUNCH_KEY: from "launchKey" field returned by Game List API
const char* APPLET_ID = "691acb162dcfadc65a0fdb77"; // Get from game list
const char* LAUNCH_KEY = "691acb162dcfadc65a0fdb77"; // Get from game list
const char* ACCESS_TOKEN = "your-access-token";

// Build launch config
// launchKey must use value from Game List API
char launchConfig[2048];
snprintf(launchConfig, sizeof(launchConfig), R"({
"launchKey": "%s",
"accessToken": "%s",
"userId": "developer",
"debug": true,
"mute": false
})", LAUNCH_KEY, ACCESS_TOKEN);

// Launch the game
// First parameter APPLET_ID is the "id" field returned by Game List API
appletMgr->LaunchApplet(
APPLET_ID,
launchConfig,
strlen(launchConfig),
OnLaunchComplete
);

std::cout << "Game launch request sent..." << std::endl;

3.7 Cleanup Resources​

// Wait for game to finish (in real app, use event loop)
std::this_thread::sleep_for(std::chrono::seconds(60));

// Close game
appletMgr->CloseApplet(APPLET_ID);

// Cleanup
appletMgr->Release();
service->UninitializeBrowsingCore();
service->Release();

// Unload library
#ifdef _WIN32
FreeLibrary(hDll);
#else
dlclose(hDll);
#endif

std::cout << "Cleanup complete" << std::endl;

4. Complete Minimal Example​

#ifdef _WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif

#include <iostream>
#include <thread>
#include <chrono>
#include <atomic>
#include "IBrowsingService.h"
#include "IAppletManagerV3.h"

// SDK Configuration
const char* SDK_KEY = "AKIDcv9N9wkDXKZ7gDoB2avKlu0N8tnS";
const char* SDK_SECRET = "sp9ZsGlNLmTSX9o0sa29C5FwmxemUV8A";
const char* ACCESS_TOKEN = "w2uAAaGN0WOdmNiNLcKQML4JT3O-5ng2hx2Mur_1dvY01ef";

// Game Configuration - these values should be obtained from Game List API
// APPLET_ID: "id" field returned by Game List API
// LAUNCH_KEY: "launchKey" field returned by Game List API
const char* APPLET_ID = "691acb162dcfadc65a0fdb77";
const char* LAUNCH_KEY = "691acb162dcfadc65a0fdb77";

// Global state
std::atomic<bool> g_launchCompleted{false};
std::atomic<int> g_launchResultCode{-1};

// Launch callback
void OnLaunchComplete(const char* app_id, int result_code, const char* error_desc) {
g_launchResultCode = result_code;
g_launchCompleted = true;

if (result_code == WMPF_ERRCODE_SUCCESS) {
std::cout << "Game launched: " << app_id << std::endl;
} else {
std::cerr << "Launch failed: " << (error_desc ? error_desc : "Unknown error") << std::endl;
}
}

int main() {
// 1. Load library
#ifdef _WIN32
HMODULE hDll = LoadLibraryA("host\\webglhost_export.dll");
if (!hDll) {
std::cerr << "Failed to load DLL" << std::endl;
return 1;
}
typedef IBrowsingService* (*GetBrowsingServiceFunc)();
GetBrowsingServiceFunc GetBrowsingService =
(GetBrowsingServiceFunc)GetProcAddress(hDll, "GetBrowsingService");
#else
void* hDll = dlopen("host/libwebglhost_export.dylib", RTLD_LAZY);
if (!hDll) {
std::cerr << "Failed to load dylib: " << dlerror() << std::endl;
return 1;
}
typedef IBrowsingService* (*GetBrowsingServiceFunc)();
GetBrowsingServiceFunc GetBrowsingService =
(GetBrowsingServiceFunc)dlsym(hDll, "GetBrowsingService");
#endif

if (!GetBrowsingService) {
std::cerr << "Failed to get GetBrowsingService" << std::endl;
return 1;
}

// 2. Get service instance
IBrowsingService* service = GetBrowsingService();
if (!service) {
std::cerr << "Failed to get service instance" << std::endl;
return 1;
}

// 3. Initialize SDK
char config[1024];
snprintf(config, sizeof(config), R"({
"sdkKey": "%s",
"sdkSecret": "%s",
"debug": true
})", SDK_KEY, SDK_SECRET);

std::cout << "Initializing SDK..." << std::endl;
int result = service->InitializeBrowsingCore(config, "", nullptr);

if (result != WMPF_ERRCODE_SUCCESS) {
std::cerr << "Init failed: " << result << std::endl;
return 1;
}
std::cout << "SDK initialized" << std::endl;

// 4. Get applet manager
IAppletManagerV3* appletMgr = nullptr;
result = service->QueryInterface("IAppletManagerV3", (void**)&appletMgr);

if (result != WMPF_ERRCODE_SUCCESS || !appletMgr) {
std::cerr << "Failed to get IAppletManagerV3" << std::endl;
return 1;
}
std::cout << "Got IAppletManagerV3" << std::endl;

// 5. Launch game
// launchKey is from "launchKey" field returned by Game List API
char launchConfig[2048];
snprintf(launchConfig, sizeof(launchConfig), R"({
"launchKey": "%s",
"accessToken": "%s",
"userId": "developer",
"debug": true
})", LAUNCH_KEY, ACCESS_TOKEN);

std::cout << "Launching game..." << std::endl;
// APPLET_ID is from "id" field returned by Game List API
appletMgr->LaunchApplet(APPLET_ID, launchConfig, strlen(launchConfig), OnLaunchComplete);

// 6. Wait for launch
while (!g_launchCompleted) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

if (g_launchResultCode != WMPF_ERRCODE_SUCCESS) {
std::cerr << "Game launch failed, exiting..." << std::endl;
appletMgr->Release();
service->UninitializeBrowsingCore();
service->Release();
return 1;
}

// 7. Keep running
std::cout << "\nGame is running. Press Ctrl+C to exit..." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(60));

// 8. Cleanup
std::cout << "\nClosing game..." << std::endl;
appletMgr->CloseApplet(APPLET_ID);

appletMgr->Release();
service->UninitializeBrowsingCore();
service->Release();

#ifdef _WIN32
FreeLibrary(hDll);
#else
dlclose(hDll);
#endif

std::cout << "Done!" << std::endl;
return 0;
}

5. Build and Run​

The Demo project provides convenient scripts to automatically extract the SDK, build, and run the sample program.

5.1 Windows​

One-click build and run:

cd scripts
build-and-run.bat

Step-by-step operations:

cd scripts

REM 1. Build project (auto-extracts SDK and runtime)
build.bat

REM 2. Run sample
run.bat

REM 3. Clean build artifacts
clean.bat

Manual build with CMake:

# First manually extract files from native_sdk/windows/

mkdir build
cd build
cmake .. -G "Visual Studio 16 2019" -A x64
cmake --build . --config Release
.\Release\demo.exe

5.2 macOS​

One-click build and run:

cd scripts
chmod +x *.sh
./build-and-run.sh

Step-by-step operations:

cd scripts
chmod +x *.sh

# 1. Build project (auto-extracts SDK and runtime)
./build.sh

# 2. Run sample
./run.sh

# 3. Clean build artifacts
./clean.sh

Manual build with CMake:

# First manually extract files from native_sdk/mac/

mkdir build
cd build
cmake ..
make
./demo

Build script notes:

  • Build scripts automatically detect system architecture (x64 or ARM64)
  • Automatically merge and extract split archives
  • Place SDK and runtime files in the correct locations
  • For detailed instructions, refer to scripts/USAGE.md

6. System Requirements​

6.1 Windows​

  • Operating System: Windows 10/11 (64-bit)
  • Development Tools: Visual Studio 2019 or higher
  • C++ Standard: C++17 or higher
  • Dependencies: ws2_32.lib (Windows Sockets)

6.2 macOS​

  • Operating System: macOS 10.15+ (Catalina or higher)
  • Development Tools: Xcode Command Line Tools
  • C++ Standard: C++17 or higher
  • Dependencies: System frameworks (auto-linked)

7. Common Issues​

7.1 DLL/dylib Load Failed​

Windows:

  • Ensure webglhost_export.dll is in the same directory as the executable or in the system path
  • Check if Visual C++ Redistributable is installed

macOS:

  • Use absolute path or relative path to load the dylib
  • Check library signature and permissions

7.2 Initialization Failed​

  • Verify SDK Key and Secret
  • Ensure runtime file runtime/webglhost-runtime.exe (Windows) or runtime/webglhost-runtime.app (macOS) exists
  • Check network connection

7.3 Game Launch Failed​

  • Check error description for details

8. Next Steps​