PremiumAds Google AdMob Adapter V2 — Cocos2d-x
Integrate PremiumAds as a mediation ad source in your Cocos2d-x C++ game. The adapter is a Google AdMob mediation custom event — your game continues to call Google Mobile Ads SDK to load ads; AdMob's waterfall picks PremiumAds when configured.
Supported formats: Banner (incl. MREC 300×250, Leaderboard, Adaptive), Interstitial, Rewarded, Rewarded Interstitial, Native, App Open
Reference repo: premium-ads/googleads-adapter-v2-cocos2dx
Prerequisites
| Requirement | Version |
|---|---|
| Cocos2d-x | 3.15.x (tested 3.15.1) |
| Android Studio | Hedgehog or newer |
| Android Gradle Plugin | 8.2.2+ |
| Gradle | 8.2+ |
| Android NDK | r25c or newer (tested r27) |
Android minSdk | 21 |
| Xcode | 15+ (tested 17) |
| iOS deployment target | 13.0+ |
| Google Mobile Ads SDK (Android) | play-services-ads:23.6.0+ |
| Google Mobile Ads SDK (iOS) | Google-Mobile-Ads-SDK ~> 13.0 |
Cocos2d-x 3.15.1 is from 2017 and requires toolchain modernization patches to build under modern Xcode/Android Studio (AGP 8 + Gradle 8 + NDK 27 on Android; deployment target 13.0 + a prebuilt-arch helper on iOS). The reference repo ships these patches inline so you can clone and build directly.
1. Copy the Plugin Files into Your Project
From the reference repo, copy two folders into your Cocos2d-x project's Classes/:
Classes/PremiumAdsAdapter/— the plugin (1 method:setDebug())Classes/AdMobBridge/— the hand-rolled GMA C++ bridge for all 6 ad formats
YourGame/
├── Classes/
│ ├── PremiumAdsAdapter/PremiumAdsAdapter.{h,cpp}
│ └── AdMobBridge/
│ ├── AdMobBridgeCpp.h
│ ├── Banner.{h,cpp}
│ ├── Interstitial.{h,cpp}
│ ├── Rewarded.{h,cpp}
│ ├── RewardedInterstitial.{h,cpp}
│ ├── AppOpen.{h,cpp}
│ └── NativeAd.{h,cpp}
Also copy the matching native peers:
- Android Java:
proj.android-studio/app/src/main/java/net/premiumads/cocos2dx/(one bridge class per format) - iOS Obj-C++:
proj.ios_mac/ios/{PremiumAdsAdapter,AdMobBridge}/(.h + .mm) - Android layout:
proj.android-studio/app/src/main/res/layout/native_ad_template.xml(Native ad template)
2. Android — Gradle Dependencies
proj.android-studio/build.gradle
allprojects {
repositories {
google()
mavenCentral()
maven { url 'https://repo.premiumads.net/artifactory/mobile-ads-sdk/' }
}
}
proj.android-studio/app/build.gradle
android {
namespace 'com.your.package'
compileSdkVersion 34
ndkVersion "27.0.12077973"
defaultConfig {
applicationId 'com.your.package'
minSdkVersion 21
targetSdkVersion 34
multiDexEnabled true
externalNativeBuild {
ndkBuild { abiFilters 'armeabi-v7a', 'arm64-v8a' }
}
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.gms:play-services-ads:23.6.0'
implementation 'net.premiumads.sdk:admob-adapter-v2:1.0.9'
}
3. Android — Manifest & Application init
AndroidManifest.xml (note: AdMob meta-data must be at <application> level, not <activity>):
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<application android:name=".MainApplication" ...>
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY" />
<meta-data
android:name="android.app.lib_name"
android:value="cocos2dcpp"/>
<activity
android:name="com.google.android.gms.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
android:theme="@android:style/Theme.Translucent" />
</application>
</manifest>
MainApplication.java — initialize MobileAds before the Cocos2d-x activity starts:
package com.your.package;
import androidx.multidex.MultiDexApplication;
import com.google.android.gms.ads.MobileAds;
public final class MainApplication extends MultiDexApplication {
@Override public void onCreate() {
super.onCreate();
MobileAds.initialize(this, status -> { /* ready */ });
}
}
4. Android — Android.mk
Add the bridge sources to LOCAL_SRC_FILES and use LOCAL_WHOLE_STATIC_LIBRARIES so engine JNI symbols are exported in the final libcocos2dcpp.so:
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/PremiumAdsAdapter/PremiumAdsAdapter.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/Banner.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/Interstitial.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/Rewarded.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/RewardedInterstitial.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/AppOpen.cpp
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge/NativeAd.cpp
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../../../../../Classes/AdMobBridge \
$(LOCAL_PATH)/../../../../../Classes/PremiumAdsAdapter
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static
5. iOS — Podfile
platform :ios, '13.0'
use_frameworks!
target 'YourGame-mobile' do
pod 'Google-Mobile-Ads-SDK', '~> 13.0'
pod 'PremiumAdsGoogleAdapter', '~> 1.0.6'
end
Run pod install.
6. iOS — Info.plist & AppDelegate
Add to Info.plist:
<key>GADApplicationIdentifier</key>
<string>ca-app-pub-XXXXXXXXXXXXXXXX~YYYYYYYYYY</string>
<key>NSUserTrackingUsageDescription</key>
<string>This identifier will be used to deliver personalized ads to you.</string>
<key>SKAdNetworkItems</key>
<array>
<!-- See https://developers.google.com/admob/ios/ios14 for the canonical list. -->
</array>
In AppDelegate.m / AppController.mm — initialize MobileAds before Cocos2d-x bootstraps:
#import <GoogleMobileAds/GoogleMobileAds.h>
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GADMobileAds.sharedInstance startWithCompletionHandler:nil];
// ... existing Cocos2d-x bootstrap
return YES;
}
7. Use the C++ API in Your Game
#include "PremiumAdsAdapter/PremiumAdsAdapter.h"
#include "AdMobBridge/Banner.h"
#include "AdMobBridge/Interstitial.h"
#include "AdMobBridge/Rewarded.h"
// Once at app start (verbose adapter logs):
premiumads::PremiumAdsAdapter::setDebug(true);
// Banner
admob::Banner::setListener([](admob::BannerEvent e, const std::string& m) {
cocos2d::log("[Banner] event=%d %s", (int)e, m.c_str());
});
admob::Banner::create("ca-app-pub-XXX/YYY",
admob::BannerSize::MediumRectangle_300x250, // or Banner_320x50, Leaderboard_728x90, Adaptive
admob::BannerPosition::Bottom);
// Interstitial (load → show pattern)
admob::Interstitial::setListener(...);
admob::Interstitial::load("ca-app-pub-XXX/YYY");
// later, when you want to display:
if (admob::Interstitial::isReady()) admob::Interstitial::show();
// Rewarded — same pattern, listener also receives UserEarnedReward(7) with msg "type|amount"
admob::Rewarded::load("ca-app-pub-XXX/YYY");
admob::Rewarded::show();
// NativeAd — bind() overlays a native UIView/FrameLayout at game-coords
admob::NativeAd::load("ca-app-pub-XXX/YYY");
// after Loaded event:
admob::NativeAd::bind(designX, designY, designW, designH);
8. Configure AdMob Custom Event
For each ad unit you want to mediate through PremiumAds, add a custom event in the AdMob console:
| Field | Value |
|---|---|
| Class name (Android) | net.premiumads.sdk.adapter.PremiumAdsAdapter |
| Class name (iOS) | PremiumAdsAdapter |
| Parameter | PremiumAds Adunit |
| eCPM | start at $0.10 to test, then tune |
After publishing the mediation change (5–30 min propagation), filter logs for [PremiumAdsAdapter]. If you see the line, the waterfall reached PremiumAds.
Troubleshooting
UnsatisfiedLinkError: nativeSetAudioDeviceInfoat boot: the manifest'sandroid.app.lib_namemeta-data must be a child of<application>, NOT<activity>.Cocos2dxActivity.onLoadNativeLibraries()reads it viaPackageManager.GET_META_DATAonApplicationInfo.- JNI symbols missing despite
.sobuild success: useLOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static(notLOCAL_STATIC_LIBRARIES) so engine symbols stay in the final dynamic export table. - iOS link fails with "building for 'iOS-simulator', but linking in object file built for 'iOS'": Cocos2d-x 3.15.1 ships prebuilt third-party libs as arm64-iphoneos only. Run the reference repo's
tools/strip-prebuilt-platform.shonce after symlinking the engine — it stripsLC_VERSION_MIN_IPHONEOSfrom prebuilt arm64 objects so ld treats them as platform-neutral, and patches the two iOS 26 SDK source compatibility issues (CCFontAtlas.cppiconv_t cast +CCFileUtils.cppsystem() guard). HelloWorld::init()SIGSEGV on modern NDK: the stock cocos2d-x 3.15.1 template scene crashes on NDK 27. Replace with your own scene or copy the reference repo'sHelloWorldScene.cpp.- Adapter never appears in
MobileAds.initializeadapter map: confirm the AAR/Pod is actually linked (./gradlew :app:dependencies | grep premium,pod list | grep PremiumAds).
What gets shipped
PremiumAds Cocos2d-x integration is mediation custom-event only — your game continues to use Google Mobile Ads SDK directly. The adapter activates only when AdMob's waterfall picks it for a given ad unit. No code changes to your existing ad loading logic are required beyond installing the plugin.
Demo project
Clone the reference repo for a working sample with all 6 formats wired up:
git clone https://github.com/premium-ads/googleads-adapter-v2-cocos2dx.git
cd googleads-adapter-v2-cocos2dx
ln -s ~/cocos-installs/cocos2d-x-cocos2d-x-3.15.1 cocos2d
# Android
cd proj.android-studio && ./gradlew assembleDebug
# iOS — Apple Silicon Mac simulator: run the platform-strip script first
cd .. && bash tools/strip-prebuilt-platform.sh
cd proj.ios_mac/ios && pod install
xcodebuild -workspace GoogleAdsCocos2dxSample.xcworkspace \
-scheme GoogleAdsCocos2dxSample-mobile \
-sdk iphonesimulator build CODE_SIGNING_ALLOWED=NO