集成指南
简介
本文档面向接入 MG Ads SDK 的开发者,介绍如何正确接入各类广告功能。
⚠️ 重要提示:在调用广告功能之前,必须依次完成 CMP 接口和 SDK 初始化接口的调用。两者缺一不可。具体请参考CMP与SDK初始化接入指南。
MG Ads 支持以下广告类型:
| 序号 | 广告类型 | 默认尺寸 | 支持 media 类型 |
|---|---|---|---|
| 1 | 全屏广告 | 1920×1080 | image、web、video |
| 2 | 退屏广告 | - | - |
| 3 | 横幅广告 | 728×90 | image、web |
| 4 | 插屏广告 | 1024×768 | image、web、video |
| 5 | 对联广告 | 300×600 | image、web |
| 6 | 激励广告 | 1024×768 | web、video |
| 7 | 信息流广告 | - | image、web、video |
| 8 | 嵌入式广告 | - | image、web、video |
广告调用流程
应用启动
↓
调用 SetAppId()
↓
调用 OpenCmp()
↓
等待用户完成选择
↓
调用 Initialize()
↓
SDK 初始化完成
↓
调用广告接口
↓
广告展示
⚠️ 强制要求:所有广告接口必须在 Initialize() 成功完成之后调用。
接入前准备
步骤一:引入SDK
hDLL = LoadLibrary(L"MgAdSDKCSharpDLL.dll");
步骤二:完成 CMP 与 SDK 初始化
请参考CMP与SDK初始化接入指南,确保完成:
-
OpenCmp()
-
Initialize()
步骤三:创建广告位
登录 MG Ads 开发者后台 创建广告位,并获取广告位 ID(AdUnitId)。
开发者可参考 MG Ads 开发者文档中的广告位创建说明:MG Ads - 开发者文档中心 | 完整的SDK接入指南与API参考 | MG Ads
步骤四:调用广告接口
根据业务场景选择对应广告类型:
| 使用场景 | 推荐广告类型 |
|---|---|
| 游戏启动页 | 全屏广告 |
| 游戏暂停页 | 插屏广告 |
| 游戏主界面 | 横幅广告 |
| 游戏结算页 | 激励广告 |
| 游戏退出时 | 退屏广告 |
| 自定义 UI 区域 | 信息流或嵌入式广告 |
广告素材类型说明
每种广告类型均支持通过 media 参数指定素材类型,非必填,传空时随机返回MG后台已开启的素材类型。可选值如下:
| media 值 | 说明 | 广告来源 |
|---|---|---|
image | 图片广告,默认支持 | MG |
web | 网页广告,默认不开放,如需使用请在创建广告位后联系 MG 产品经理申请开通权限 | |
video | 视频广告,默认支持(部分广告类型支持) | MG |
⚠️ 重要提示:Web 类型广告(media 设置为
"web")默认不开放,如需使用,请在创建广告位后联系 MG 产品经理申请开通权限。
步骤五:处理广告结果
调用结果通过异步回调事件返回。
广告接入
⚠️ 重要提示:广告功能需要开发者创建广告容器,需在UI线程中调用广告接口。
全屏广告
说明:全屏广告会覆盖整个应用界面,适用于游戏启动页、场景切换页、关卡开始前等场景。
void ShowAd(const char* jsonParam)
Json参数说明
| 参数 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| unitId | string | 必填 | 广告位唯一标识,32位小写字母数字组合,在 MG 广告后台创建获取 |
| adType | int | 必填 | 广告类型,全屏广告请使用 1 |
| handle | int | 必填 | 广告容器的句柄 |
| parentWidth | int | 必填 | 广告容器的宽 |
| parentHeight | int | 必填 | 广告容器的高 |
| appType | int | 必填 | 应用类型。1:App , 2:Cocos等引擎开发的游戏 |
| media | string | 可选 | 支持的素材类型,传空时随机返回MG后台已开启的素材类型。可用的值包括: ● image:图片广告,默认支持 ● web:网页广告,需联系 MG 产品经理申请开通权限 ● video:视频广告,默认支持 |
返回值说明
调用结果通过异步回调事件返回。
完整示例代码
const char* FullScreenAdUnitId = "b871f83c5e8845f1b43325561bcdd6c7";
const char* ExitAdUnitId = "5076eab6ae1042b6b92f73ea01981475";
const char* BannerUnitId = "cb7d9688a2d9499992febb6b642b3625";
const char* InterstitialUnitId = "2cb66a1301404561881a3f26b6ce5ba7";
const char* CoupletUnitId = "b502f6e6281c43e4b28ea22503471039";
const char* RewardedUnitId = "2ae60936ba664fbfb7d92ce3a19c2915";
const char* FeedUnitId = "f152f6caf7a8440f8510bc31534baf4e";
const char* EmbeddedUnitId = "4192966a9db343f48dd2f6308ea9ec30";
//调用sdk的广告接口
void showAd(const char* json) {
try
{
// 确保在调用前COM已初始化
if (!g_comInitialized) {
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr)) {
g_comInitialized = true;
}
}
ShowAd func = (ShowAd)GetProcAddress(hDLL, "ShowAd");
if (func) {
func(json);
}
}
catch (...)
{
}
}
//全屏广告
case ID_BTN_AD1:
{
CreateSplashScreenAdPanel(g_hwndMain);//创建全屏广告容器
RECT clientRect;
if (GetClientRect(hWnd, &clientRect)) {
int clientWidth = clientRect.right - clientRect.left;
int clientHeight = clientRect.bottom - clientRect.top;
nlohmann::json json_obj = {
{"unitId", FullScreenAdUnitId},
{"appType", 1},
//{"media", "web"},
{"adType", 1},
{"handle", reinterpret_cast<int>(g_hwndMain)},
{"parentWidth", clientWidth},
{"parentHeight", clientHeight}
};
std::string jsonStr = json_obj.dump();
showAd(jsonStr.c_str());
}
break;
}
横幅广告
说明:横幅广告通常固定显示在界面底部,适用于游戏主界面等场景。
void ShowAd(const char* jsonParam)
参数说明
| 参数 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| unitId | string | 必填 | 广告位唯一标识,32位小写字母数字组合,在 MG 广告后台创建获取 |
| adType | int | 必填 | 广告类型,Banner请使用 3 |
| handle | int | 必填 | 广告容器的句柄 |
| appType | int | 必填 | App固定值 1 |
| media | string | 可选 | 支持的素材类型,传空时随机返回MG后台已开启的素材类型。可用的值包括: ● image:图片广告,默认支持 ● web:网页广告,需联系 MG 产品经理申请开通权限 ● video:视频广告,默认支持 |
返回值说明
调用结果通过异步回调事件返回。
完整示例代码
case ID_BTN_AD3:
{
CreateBannerAdPanel(hWnd);
int containerHandle = reinterpret_cast<int>(g_hPnlBanner);
nlohmann::json json_obj = {
{"appType", 1},
{"unitId", BannerUnitId},
{"adType", 3},//Banner
{"handle", containerHandle}
};
std::string jsonStr = json_obj.dump();
showAd(jsonStr.c_str());
break;
}
插屏广告
说明:插屏广告会在应用流程节点弹出展示,适用于关卡结束、页面切换、游戏暂停等场景。
void ShowAd(const char* jsonParam)
参数说明
| 参数 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| unitId | string | 必填 | 广告位唯一标识,32位小写字母数字组合,在 MG 广告后台创建获取 |
| adType | int | 必填 | 广告类型,插屏广告请使用 4 |
| handle | int | 必填 | 广告容器的句柄 |
| appType | int | 必填 | 应用类型。1:App , 2:Cocos等引擎开发的游戏 |
| media | string | 可选 | 支持的素材类型,传空时随机返回MG后台已开启的素材类型。可用的值包括: ● image:图片广告,默认支持 ● web:网页广告,需联系 MG 产品经理申请开通权限 ● video:视频广告,默认支持 |
返回值说明
调用结果通过异步回调事件返回。
完整示例代码
case ID_BTN_AD4:
{
CreateInterstitialAdPannel(hWnd);
nlohmann::json json_obj = {
{"appType", 1},
{"unitId", InterstitialUnitId},
{"adType", 4},//Interstitial
{"handle", reinterpret_cast<int>(g_hPnlInterstitial)}
};
std::string jsonStr = json_obj.dump();
showAd(jsonStr.c_str());
break;
}
对联广告
说明:对联广告会固定显示在界面左右两侧,适用于 PC 端网页游戏等场景。
void ShowAd(const char* jsonParam)
参数说明
| 参数 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| unitId | string | 必填 | 广告位唯一标识,32位小写字母数字组合,在 MG 广告后台创建获取 |
| adType | int | 必填 | 广告类型,对联广告请使用 5 |
| handle | int | 必填 | 左侧广告容器的句柄 |
| handle2 | int | 必填 | 右侧广告容器的句柄 |
| appType | int | 必填 | App固定值 1 |
| media | string | 可选 | 支持的素材类型,传空时随机返回MG后台已开启的素材类型。可用的值包括: ● image:图片广告,默认支持 ● web:网页广告,需联系 MG 产品经理申请开通权限 ● video:视频广告,默认支持 |
返回值说明
调用结果通过异步回调事件返回。
完整示例代码
case ID_BTN_AD5:
{
CreateCoupletAdPannel(hWnd);
nlohmann::json json_obj = {
{"appType", 1},
{"unitId", CoupletUnitId},
{"adType", 5},//Couplet
{"handle", reinterpret_cast<int>(g_hPnlCoupletLeft)},
{"handle2", reinterpret_cast<int>(g_hPnlCoupletRight)}
};
std::string jsonStr = json_obj.dump();
showAd(jsonStr.c_str());
break;
}
激励广告
说明:激励视广告用于用户观看完整广告后获得奖励,适用于游戏结算页、复活、领取双倍奖励等场景。
void ShowAd(const char* jsonParam)
参数说明
| 参数 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| unitId | string | 必填 | 广告位唯一标识,32位小写字母数字组合,在 MG 广告后台创建获取 |
| adType | int | 必填 | 广告类型,激励广告请使用 6 |
| handle | int | 必填 | 广告容器的句柄 |
| appType | int | 必填 | 应用类型。1:App , 2:Cocos等引擎开发的游戏 |
| width | int | 必填 | 广告容器的宽,默认1024 |
| height | int | 必填 | 广告容器的高,默认768 |
| media | string | 可选 | 支持的素材类型,传空时随机返回MG后台已开启的素材类型。可用的值包括: ● image:图片广告,默认支持 ● web:网页广告,需联系 MG 产品经理申请开通权限 ● video:视频广告,默认支持 |
| comment | string | 可选 | 开发者自定义参数(需 URL 编码) |
返回值说明
调用结果通过异步回调事件返回。
奖励发放流程
┌─────────────────┐
│ 调用 ShowAd() │
│ (传入激励广告参数) │
└────────┬────────┘
↓
┌─────────────────┐
│ 用户观看广告 │
└────────┬────────┘
↓
┌─────────────────────────────────────────┐
│ 广告播放完成,广告关闭回调事件返回 Json 格式参数 │
└────────┬────────────────────────────────┘
↓
┌─────────────────┐ ┌─────────────────┐
│ completeStatus=1 │ │ completeStatus=0│
│ (完整观看) │ │ (未完整观看) │
└────────┬────────┘ └────────┬────────┘
↓ ↓
┌─────────────────┐ ┌─────────────────┐
│ 发放游戏奖励 │ │ 不发放奖励 │
└────────┬────────┘ └─────────────────┘
↓
┌─────────────────────────────┐
│ 调用 ReportAdRewardFulfillment() │
│ 通知 MG 后台核销 │
└─────────────────────────────┘
完整示例代码
//在UI线程中调用广告接口
case ID_BTN_AD6:
{
CreateRewardAdPannel(hWnd);
nlohmann::json json_obj = {
{"appType", 1},
{"unitId", RewardedUnitId},
{"comment", "abc123"},//Passthrough parameter, the frontend needs to perform urlEncode; it will be returned unchanged in the ad close callback event.
{"adType", 6},
{"handle", reinterpret_cast<int>(g_hPnlReward)},
{"width", 1024},
{"height", 768}
};
std::string jsonStr = json_obj.dump();
showAd(jsonStr.c_str());
break;
}
void onAdCloseEvent(char* s) {
AppendLog(L"onAdCloseEvent: %hs", s);
//...
// 在UI线程中销毁广告容器
try
{
nlohmann::json json_obj = nlohmann::json::parse(s);
std::string unitId = json_obj["unitId"];
if (unitId == RewardedUnitId)
{//Rewarded
DestroyWindow(g_hPnlReward);
g_hPnlReward = NULL;
int completeStatus = json_obj["completeStatus"];
if (completeStatus == 1)
{
std::string resourceId = json_obj["resourceId"];
std::string materialId = json_obj["materialId"];
std::string rewardId = json_obj["rewardId"];
//广告播放完毕,可以发奖励
//...
//向MG报告
reportAdRewardFulfillment(unitId.c_str(), resourceId.c_str(), materialId.c_str(), rewardId.c_str());
AppendLog(L"reportAdRewardFulfillment Async: %hs", rewardId.c_str());
}
}
}
catch (...)
{
}
}
💡 提示:
-
激励广告需在广告关闭回调中根据 completeStatus 判断是否发奖,避免未完整观看即发放奖励。
-
comment 字段可用于传递游戏内参数(如奖励类型、数量等),请务必在传入时进行 URL 编码,解码后使用。
-
成功发奖后应调用 ReportAdRewardFulfillment 通知 MG 后台完成核销。
信息流广告
说明:信息流广告允许开发者指定广告展示容器,适用于信息流广告、列表内嵌广告等场景。开发者需要提前在 Form 中定义一个容器控件(如 Panel),然后将该容器传入 SDK。
void ShowAd(const char* jsonParam)
参数说明
| 参数 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| unitId | string | 必填 | 广告位唯一标识,32位小写字母数字组合,在 MG 广告后台创建获取 |
| adType | int | 必填 | 广告类型,信息流广告请使用 7 |
| handle | int | 必填 | 广告容器的句柄 |
| appType | int | 必填 | App固定值 1 |
| width | int | 必填 | 广告容器的宽 |
| height | int | 必填 | 广告容器的高 |
| media | string | 可选 | 支持的素材类型,传空时随机返回MG后台已开启的素材类型。可用的值包括: ● image:图片广告,默认支持 ● web:网页广告,需联系 MG 产品经理申请开通权限 ● video:视频广告,默认支持 |
返回值说明
调用结果通过异步回调事件返回。
完整示例代码
case ID_BTN_AD7:
{
int containerHandle = reinterpret_cast<int>(g_hPnlFeed);
nlohmann::json json_obj = {
{"appType", 1},
{"unitId", FeedUnitId},
{"adType", 7},
{"width", 400},//Feed requires passing in the container's width and height.
{"height", 50},
{"handle", containerHandle}
};
std::string jsonStr = json_obj.dump();
showAd(jsonStr.c_str());
break;
}
嵌入式广告
说明:嵌入式广告允许开发者指定广告展示容器,适用于页面内嵌广告、自定义 UI 区域的广告展示等场景。开发者需要提前在 Form 中定义一个容器控件(如 Panel),然后将该容器传入 SDK。
void ShowAd(const char* jsonParam)
参数说明
| 参数 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| unitId | string | 必填 | 广告位唯一标识,32位小写字母数字组合,在 MG 广告后台创建获取 |
| adType | int | 必填 | 广告类型,嵌入式广告请使用 8 |
| handle | int | 必填 | 广告容器的句柄 |
| appType | int | 必填 | App固定值 1 |
| width | int | 必填 | 广告容器的宽 |
| height | int | 必填 | 广告容器的高 |
| media | string | 可选 | 支持的素材类型,传空时随机返回MG后台已开启的素材类型。可用的值包括: ● image:图片广告,默认支持 ● web:网页广告,需联系 MG 产品经理申请开通权限 ● video:视频广告,默认支持 |
返回值说明
调用结果通过异步回调事件返回。
完整示例代码
case ID_BTN_AD8:
{
int containerHandle = reinterpret_cast<int>(g_hPnlEmbedded);
nlohmann::json json_obj = {
{"appType", 1},
{"unitId", EmbeddedUnitId},
{"adType", 8},
{"width", 200},//Embedded requires passing in the container's width and height.
{"height", 200},
{"handle", containerHandle}
};
std::string jsonStr = json_obj.dump();
showAd(jsonStr.c_str());
break;
}
退屏广告
说明:退屏广告是在退出游戏时触发,为了保证退出游戏时广告的弹出率,MG会分两步完成退屏广告的实现
1.在初始化完成后,将退屏广告的信息加载到内存中
2.在退出游戏时,直接打开退屏广告
void SetupExitAd(const char* exitAdUnitId)
参数说明
| 参数 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| unitId | string | 必填 | 广告位唯一标识,32位小写字母数字组合,在 MG 广告后台创建获取 |
完整示例代码
//退屏广告
//Step1.初始化成功之后,加载退屏广告资源
void onInitCompleteEvent(char* s) {
try
{
nlohmann::json json_obj = nlohmann::json::parse(s); //{"success":true,"data":""}
bool success = json_obj["success"];
if (success) {
AppendLog(L"Initialization successful");
if (auto func = (SetupExitAd)GetProcAddress(hdll, "SetupExitAd")) {
func(ExitAdUnitId); // 加载退屏广告资源
}
}
}
catch (...)
{
}
}
// Step2.在程序关闭时,弹出展示退屏广告
case ID_BTN_EXITAD:
{
if (auto func = (ShowExitAdBlocking)GetProcAddress(hdll, "ShowExitAdBlocking")) {
func();
AppendLog(L"show fallback screen advert");
}
break;
}
广告关闭事件
说明:注册广告关闭的回调事件,一般在页面的构造函数中进行
事件返回参数说明
| 参数名 | 参数描述 | 示例 |
|---|---|---|
| unitId | 开发者传入的广告位ID | e333abaf22404c4a8d382c1e7ba42076 |
| advertStatus | 广告位状态 | 1:广告正常;2:广告被后台关闭;3:没有广告素材 |
| 以下是仅激励视频广告拥有的参数 | ||
| completeStatus | 广告的播放状态 | 1:广告播放完毕,可以发奖励;0:广告未播放完毕 |
| comment | 由开发者传入的透传参数,经过 url 编码 | abc%2c123 |
| rewardId | 奖励的MG订单号,游戏发奖后向MG报告核销时使用 | String |
| resourceId | 资源Id | String |
| materialId | 素材 Id | String |
完整示例代码
//App启动
void InitMgAdSdk(HWND hWnd) {
if (hDLL) return;
hDLL = LoadLibrary(L"MgAdSDKCSharpDLL.dll");
if (hDLL) {
//广告关闭回调事件
if (auto func = (AdCloseEvent)GetProcAddress(hDLL, "AdCloseEvent"))
func(onAdCloseEvent);
//广告预缓存回调事件
if (auto func = (AdPreloadEvent)GetProcAddress(hDLL, "AdPreloadEvent"))
func(onAdPreloadEvent);
//预缓存播放回调事件,按需使用
if (auto func = (AdShowPreloadEvent)GetProcAddress(hDLL, "AdShowPreloadEvent"))
func(onAdShowPreloadEvent);
//...
}
}
void onAdCloseEvent(char* s) {
AppendLog(L"onAdCloseEvent: %hs", s);
//...
// 在UI线程中销毁广告容器
try
{
nlohmann::json json_obj = nlohmann::json::parse(s);
std::string unitId = json_obj["unitId"];
if (unitId == FullScreenAdUnitId)
{//在UI线程中销毁广告容器
DestroyWindow(g_hPnlSplashScreen);
g_hPnlSplashScreen = NULL;
}
else if (unitId == RewardedUnitId)
{//Rewarded
DestroyWindow(g_hPnlReward);
g_hPnlReward = NULL;
int completeStatus = json_obj["completeStatus"];
if (completeStatus == 1)
{
std::string resourceId = json_obj["resourceId"];
std::string materialId = json_obj["materialId"];
std::string rewardId = json_obj["rewardId"];
//广告播放完毕,可以发奖励
//...
//向MG报告
reportAdRewardFulfillment(unitId.c_str(), resourceId.c_str(), materialId.c_str(), rewardId.c_str());
AppendLog(L"reportAdRewardFulfillment Async: %hs", rewardId.c_str());
}
}
}
catch (...)
{
}
}
广告预加载功能
⚠️ 适用场景说明:预加载功能仅适用于接入了多个广告平台(如同时接入了AppLovin、Vungle、优量汇、MG 等多套 SDK)的开发者。如果仅接入 MG Ads 单一平台,建议直接使用 ShowAd(),无需使用预加载模式。
预加载功能提供两个独立的接口,帮助您在广告展示前提前准备素材,提升展示成功率。
-
预加载接口(PreloadAd):提前请求并缓存广告素材
-
展示预加载广告接口(ShowPreloadAd):展示已预加载成功的广告
💡 提示:预加载功能适用于所有广告类型。您可以在需要展示广告之前,提前调用预加载接口,待广告准备就绪后再通过展示接口进行展示。
预加载核心规则
| 规则 | 说明 |
|---|---|
| 单条缓存 | SDK 每个广告位仅缓存一条广告,在未播放完成前不能再次请求预加载 |
| 播放完成后再预加载下一条 | 广告展示完成后,才能再次调用 PreloadAd() 预加载下一条广告 |
| ID 与类型必须一致 | ShowPreloadAd() 的 unitId 和 adType 必须与 PreloadAd() 完全一致 |
最佳实践案例
场景:激励广告广告在关卡结束后用于领取双倍奖励
关卡开始前
↓
调用 PreloadAd() 预加载激励广告
↓
玩家通关
↓
调用 ShowPreloadAd() 展示广告
↓
广告播放完成
↓
开启下一关
↓
再次调用 PreloadAd() 预加载下一条
预加载接口
void PreloadAd(const char* jsonParam)
参数说明
| 参数 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| unitId | string | 必填 | 广告位唯一标识,32位小写字母数字组合,在 MG 广告后台创建获取 |
| adType | int | 必填 | 广告类型 |
| appType | int | 必填 | App固定值 1 |
| media | string | 可选 | 支持的素材类型,传空时随机返回MG后台已开启的素材类型。可用的值包括: ● image:图片广告,默认支持 ● web:网页广告,需联系 MG 产品经理申请开通权限 ● video:视频广告,默认支持 |
返回值说明
调用结果通过异步回调事件返回。
完整示例代码(插屏广告)
//在UI线程中调用广告
case ID_BTN_AD4PRELOAD: {
nlohmann::json json_obj = {
{"unitId", InterstitialUnitId},
{"appType", 1},
{"adType", 4}
};
std::string jsonStr = json_obj.dump();
preloadAd(jsonStr.c_str());
break;
}
void preloadAd(const char* json)
{
try
{
// 确保在调用前COM已初始化
if (!g_comInitialized) {
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr)) {
g_comInitialized = true;
}
}
PreloadAd func = (PreloadAd)GetProcAddress(hDLL, "PreloadAd");
if (func) {
func(json);
}
}
catch (...)
{
}
}
// 广告预加载回调事件
void onAdPreloadEvent(char* s) {
AppendLog(L"onAdPreloadEvent: %hs", s);
//eg.s = {"unitId":"a9bd7d57faef4f8cb016979284c86102","advertStatus":1,"displayStatus":0}
//...
nlohmann::json json_obj = nlohmann::json::parse(s);
std::string unitId = json_obj["unitId"];
std::int32_t adStatus = json_obj["advertStatus"];
if (adStatus == 1)
{
// 广告加载成功
if (unitId == InterstitialUnitId)
{
EnableWindow(g_hBtnInterstitialAdShow, TRUE);
}
else if (unitId == RewardedUnitId)
{
EnableWindow(g_hBtnRewardedAdShow, TRUE);
}
}
}
// 展示预加载成功的广告
int showPreloadAd(const char* json,HWND adBntHwnd)
{
try
{
if (!g_comInitialized) {
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr)) {
g_comInitialized = true;
}
}
ShowPreloadAd func = (ShowPreloadAd)GetProcAddress(hDLL, "ShowPreloadAd");
if (func) {
func(json);
AppendLog(L"show mg ad: success");
EnableWindow(adBntHwnd, FALSE);
}
}
catch (...)
{
}
return 0;
}
展示预加载广告接口
void ShowPreloadAd(const char* jsonParam)
参数说明
| 参数 | 类型 | 必要性 | 说明 |
|---|---|---|---|
| unitId | string | 必填 | 广告位唯一标识,32位小写字母数字组合,在 MG 广告后台创建获取 |
| adType | int | 必填 | 广告类型 |
| handle | int | 必填 | 广告容器的句柄 |
| appType | int | 必填 | App固定值 1 |
| media | string | 可选 | 支持的素材类型,传空时随机返回MG后台已开启的素材类型。可用的值包括: ● image:图片广告,默认支持 ● web:网页广告,需联系 MG 产品经理申请开通权限 ● video:视频广告,默认支持 |
⚠️ 注意事项:调用本接口前,请确保对应广告位已通过 PreloadAd 预加载成功。
示例代码
2.1 展示预缓存成功的全屏广告
case ID_BTN_AD1PRESHOW: {
RECT clientRect;
if (GetClientRect(hWnd, &clientRect)) {
int clientWidth = clientRect.right - clientRect.left;
int clientHeight = clientRect.bottom - clientRect.top;
nlohmann::json json_obj = {
{"unitId", FullScreenAdUnitId},
{"appType", 1},
{"adType", 1},
{"handle", reinterpret_cast<int>(g_hwndMain)},
{"parentWidth", clientWidth},//开屏需要传APP的宽高,预缓存接口也需要
{"parentHeight", clientHeight}
};
std::string jsonStr = json_obj.dump();
showPreloadAd(jsonStr.c_str(), g_hwndMain);
}
break;
}
2.2 展示预缓存成功的横幅广告
CreateBannerAdPanel(hWnd);
int containerHandle = reinterpret_cast<int>(g_hPnlBanner);
nlohmann::json json_obj = {
{"unitId", BannerUnitId},
{"appType", 1},
{"adType", 3},//Banner
{"handle", containerHandle}
};
std::string jsonStr = json_obj.dump();
showPreloadAd(jsonStr.c_str(), g_hPnlBanner);
break;
}
2.3 展示预缓存成功的插屏广告
case ID_BTN_AD4PRESHOW: {
CreateInterstitialAdPannel(hWnd);
nlohmann::json json_obj = {
{"unitId", InterstitialUnitId},
{"appType", 1},
{"adType", 4},
{"handle", reinterpret_cast<int>(g_hPnlInterstitial)}
};
std::string jsonStr = json_obj.dump();
showPreloadAd(jsonStr.c_str(), g_hBtnInterstitialAdShow);
break;
}
2.4 展示预缓存成功的对联广告
case ID_BTN_AD5PRESHOW: {
CreateCoupletAdPannel(hWnd);
nlohmann::json json_obj = {
{"unitId", CoupletUnitId},
{"appType", 1},
{"adType", 5},
{"handle", reinterpret_cast<int>(g_hPnlCoupletLeft)},
{"handle2", reinterpret_cast<int>(g_hPnlCoupletRight)}
};
std::string jsonStr = json_obj.dump();
showPreloadAd(jsonStr.c_str(), g_hPnlCoupletLeft);
break;
}
// 激励广告中发奖励请参阅 广告关闭事件
2.5 展示预缓存成功的激励广告
case ID_BTN_AD6PRESHOW: {
CreateRewardAdPannel(hWnd);
nlohmann::json json_obj = {
{"unitId", RewardedUnitId},
{"comment", "abc123"},
{"appType", 1},
{"adType", 6},
{"handle", reinterpret_cast<int>(g_hPnlReward)},
{"width", 1024},
{"height", 768}
};
std::string jsonStr = json_obj.dump();
showPreloadAd(jsonStr.c_str(), g_hBtnRewardedAdShow);
break;
}
2.6 展示预缓存成功的信息流广告
case ID_BTN_AD7PRESHOW: {
nlohmann::json json_obj = {
{"unitId", FeedUnitId},
{"comment", "abc123"},
{"appType", 1},
{"adType", 7},
{"handle", reinterpret_cast<int>(g_hPnlFeed)},
{"width", 400},
{"height", 50}
};
std::string jsonStr = json_obj.dump();
showPreloadAd(jsonStr.c_str(), g_hPnlFeed);
break;
}
2.7 展示预缓存成功的嵌入式广告
case ID_BTN_AD7PRESHOW: {
nlohmann::json json_obj = {
{"unitId", EmbeddedUnitId},
{"appType", 1},
{"adType", 8},
{"handle", reinterpret_cast<int>(g_hPnlEmbedded)},
{"width", 200},
{"height", 200}
};
std::string jsonStr = json_obj.dump();
showPreloadAd(jsonStr.c_str(), g_hPnlEmbedded);
break;
}
预加载功能调用流程
┌─────────────────────────────────────────────────────────────────┐
│ 应用启动 │
└─────────────────────────────┬───────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 调用 OpenCmp() 和 Initialize() │
└─────────────────────────────┬───────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ SDK 初始化完成 │
└─────────────────────────────┬───────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 【预加载模式】调用 PreloadAd() 预加载广告素材 │
│ (如:关卡开始前预加载) │
└─────────────────────────────┬───────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 判断预加载是否成功 │
└─────────────┬───────────────────────────────┬───────────────────┘
↓ ↓
┌───────────┐ ┌───────────┐
│ 成功(true)│ │ 失败(false)│
└─────┬─────┘ └─────┬─────┘
↓ ↓
┌─────────────────────────┐ ┌─────────────────────────────┐
│ 等待用户触发广告展示时机 │ │ 降级使用普通 ShowAd() │
│ (如:玩家通关后) │ │ 或 放弃本次广告展示 │
└─────────────┬───────────┘ └─────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 调用 ShowPreloadAd() 展示已预加载成功的广告 │
└─────────────────────────────┬───────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 广告展示完成 │
└─────────────────────────────┬───────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 再次调用 PreloadAd() 预加载下一条广告 │
│ (为下一次展示做准备) │
└─────────────────────────────────────────────────────────────────┘
常见问题(FAQ)
Q1:为什么必须先在后台创建广告位?
A:unitId 是广告请求的唯一标识,需要在 MG 广告后台预先创建并配置广告素材,才能正常请求和展示广告。
Q2:广告展示失败怎么办?
A:常见原因及解决方法:
| 错误类型 | 解决方法 |
|---|---|
| 广告位 ID 错误 | 核对后台配置的32位小写字母数字组合ID |
| 网络故障 | 检查设备网络连接 |
| 无可用广告素材 | 联系MG产品经理补充对应尺寸和格式的广告素材 |
| 预加载未完成 | 调用 ShowPreloadAd 前确保 PreloadAd 已成功 |
Q3:激励广告如何发放奖励?
A:在 广告关闭 的回调中判断 completeStatus:
-
为 1 时,表示用户完整观看视频,可发放奖励
-
发放奖励后必须调用 ReportAdRewardFulfillment() 通知 MG 后台核销
Q4:预加载功能的好处是什么?
A:
-
提前加载广告素材,减少用户等待时间
-
提高广告展示成功率
-
适用于需要精准控制广告展示时机的场景
Q5:OpenCmp 和 Initialize 未完成时能否调用广告?
A:不能。必须先完成 CMP 和 SDK 初始化,才能正常调用广告功能。否则可能导致广告请求失败或合规问题。
Q6:预加载功能应该在什么情况下使用?
A:仅当您的应用接入了多个广告平台(如同时使用Google、优量汇、MG 等多套 SDK)时,才建议使用预加载模式。单一平台场景直接使用 ShowAd() 即可。
Q7:预加载可以同时缓存多条广告吗?
A:不可以。每个广告位仅缓存一条广告,在未播放完成前不能再次请求预加载。广告展示完成后,应再次调用 PreloadAd() 预加载下一条。
Q8:ShowPreloadAd() 失败怎么办?
A:建议按以下顺序处理:
-
检查对应广告位是否预加载成功
-
检查广告位 ID 是否一致
-
检查广告类型是否一致
-
降级为 ShowAd() 普通广告展示模式
-
放弃本次广告展示
Q9:自定义广告的 容器 可以是什么类型的控件?
A:支持 Panel、ContentControl、UserControl 及其派生类。
Q10:如何主动关闭正在展示的广告?
A:移除对应的容器控件即可。