# 微信开放接口集成
本文档介绍如何在 Emscripten 项目中集成微信小游戏开放接口,实现登录、分享、支付等平台能力。
# 概述
微信开放接口模块将微信小游戏的 JavaScript API 封装为 C++ 接口,让游戏可以直接使用微信平台提供的各种能力。
# 功能特性
| 模块 | 功能 |
|---|---|
| 登录认证 | 微信登录、获取用户信息 |
| 社交分享 | 分享到好友、朋友圈、群 |
| 数据存储 | 云端数据存储与同步 |
| 广告 | 激励视频、Banner广告 |
| 支付 | 游戏内支付 |
| 系统信息 | 设备信息、网络状态 |
| 小程序跳转 | 跳转其他小程序 |
# 快速开始
# 集成到项目
# CMakeLists.txt 配置
cmake_minimum_required(VERSION 3.10)
project(MyGame)
set(WXGAMESDK_DIR "${CMAKE_CURRENT_SOURCE_DIR}/wxgamesdk")
add_executable(mygame main.cpp)
target_include_directories(mygame PRIVATE
${WXGAMESDK_DIR}/include
)
target_link_libraries(mygame
${WXGAMESDK_DIR}/lib/libwxgamesdk.a
)
set_target_properties(mygame PROPERTIES
LINK_FLAGS "\
-s WASM=1 \
-s EXPORTED_RUNTIME_METHODS='[\"ccall\", \"cwrap\", \"stringToUTF8\", \"UTF8ToString\", \"lengthBytesUTF8\", \"allocateUTF8\"]' \
--js-library ${WXGAMESDK_DIR}/jslib/SDK-Call-JS.jslib \
-Wl,--whole-archive ${WXGAMESDK_DIR}/lib/libwxgamesdk.a -Wl,--no-whole-archive"
)
# 小游戏端配置
转换后,在小游戏的 game.js 中添加:
import "./wx-wasm-sdk/index"; // 在 Module 生成之前导入
# API 参考
# 头文件
#include "wx.h"
# 登录认证
namespace wxwasmsdk {
// 登录配置
struct LoginOption {
int timeout;
std::function<void(LoginSuccessCallbackResult&)> success;
std::function<void(GeneralCallbackResult&)> fail;
std::function<void(GeneralCallbackResult&)> complete;
};
// 登录结果
struct LoginSuccessCallbackResult {
std::string code; // 用于换取 openid 的临时凭证
};
// 发起登录
void Login(LoginOption& option);
// 检查登录态是否过期
void CheckSession(CheckSessionOption& option);
}
# 用户信息
namespace wxwasmsdk {
// 获取用户信息
void GetUserInfo(GetUserInfoOption& option);
// 创建用户信息按钮
UserInfoButton* CreateUserInfoButton(CreateUserInfoButtonOption& option);
}
# 系统信息
namespace wxwasmsdk {
// 基本信息
struct AppBaseInfo {
std::string SDKVersion; // SDK 版本
std::string version; // 微信版本
std::string language; // 语言
std::string theme; // 主题
bool enableDebug; // 是否开启调试
std::string host; // 宿主环境
};
// 同步获取基本信息
AppBaseInfo GetAppBaseInfo();
// 获取系统信息
void GetSystemInfo(GetSystemInfoOption& option);
// 同步获取系统信息
SystemInfo GetSystemInfoSync();
}
# 事件监听
namespace wxwasmsdk {
// 监听小游戏显示
void OnShow(OnShowCallback& callback);
// 监听小游戏隐藏
void OnHide(OnHideCallback& callback);
// 监听复制链接
void OnCopyUrl(OnCopyUrlCallback& callback);
}
# 使用示例
# 微信登录
#include "wx.h"
#include <iostream>
void WeChatLogin() {
wxwasmsdk::LoginOption opt;
opt.timeout = 10000; // 10秒超时
opt.success = [](wxwasmsdk::LoginSuccessCallbackResult& res) {
std::cout << "登录成功!" << std::endl;
std::cout << "临时凭证 code: " << res.code << std::endl;
// 将 code 发送到自己的服务器换取 openid
SendCodeToServer(res.code);
};
opt.fail = [](wxwasmsdk::GeneralCallbackResult& res) {
std::cout << "登录失败: " << res.errMsg << std::endl;
};
opt.complete = [](wxwasmsdk::GeneralCallbackResult& res) {
std::cout << "登录流程完成" << std::endl;
};
wxwasmsdk::Login(opt);
}
void SendCodeToServer(const std::string& code) {
// 发送到后端服务器
WXHttp::HttpRequestConfig config;
config.url = "https://your-server.com/api/wx/login";
config.method = "POST";
config.headers["Content-Type"] = "application/json";
config.data = R"({"code": ")" + code + R"("})";
int request_id;
WXHttp::Request(config, &request_id);
}
# 获取系统信息
#include "wx.h"
void GetDeviceInfo() {
// 同步获取基本信息
auto appBaseInfo = wxwasmsdk::GetAppBaseInfo();
std::cout << "SDK 版本: " << appBaseInfo.SDKVersion << std::endl;
std::cout << "微信版本: " << appBaseInfo.version << std::endl;
// 异步获取完整系统信息
wxwasmsdk::GetSystemInfoOption opt;
opt.success = [](wxwasmsdk::GetSystemInfoSuccessCallbackResult& res) {
std::cout << "设备品牌: " << res.brand << std::endl;
std::cout << "设备型号: " << res.model << std::endl;
std::cout << "操作系统: " << res.system << std::endl;
std::cout << "屏幕宽度: " << res.screenWidth << std::endl;
std::cout << "屏幕高度: " << res.screenHeight << std::endl;
std::cout << "像素比: " << res.pixelRatio << std::endl;
};
wxwasmsdk::GetSystemInfo(opt);
}
# 监听小游戏生命周期
#include "wx.h"
void SetupLifecycleListeners() {
// 监听小游戏切到前台
wxwasmsdk::OnShowCallback showListener(
[](wxwasmsdk::OnShowListenerResult& res) {
std::cout << "小游戏显示" << std::endl;
std::cout << "场景值: " << res.scene << std::endl;
// 检查启动参数
if (res.query.HasMember("from")) {
std::cout << "来源: " << res.query["from"].GetString() << std::endl;
}
// 恢复游戏
ResumeGame();
}
);
wxwasmsdk::OnShow(showListener);
// 监听小游戏切到后台
wxwasmsdk::OnHideCallback hideListener(
[](wxwasmsdk::OnHideListenerResult& res) {
std::cout << "小游戏隐藏" << std::endl;
// 暂停游戏
PauseGame();
}
);
wxwasmsdk::OnHide(hideListener);
}
# 分享功能
#include "wx.h"
void SetupShare() {
// 设置分享菜单
wxwasmsdk::ShowShareMenuOption opt;
opt.withShareTicket = true;
opt.menus = {"shareAppMessage", "shareTimeline"};
wxwasmsdk::ShowShareMenu(opt);
// 监听用户点击分享
wxwasmsdk::OnShareAppMessageCallback shareListener(
[]() -> wxwasmsdk::OnShareAppMessageListenerResult {
wxwasmsdk::OnShareAppMessageListenerResult result;
result.title = "我在玩这个游戏,快来挑战我!";
result.imageUrl = "https://cdn.example.com/share.png";
result.query = "from=share&inviter=12345";
return result;
}
);
wxwasmsdk::OnShareAppMessage(shareListener);
}
// 主动分享
void ShareToFriend() {
wxwasmsdk::ShareAppMessageOption opt;
opt.title = "邀请好友一起玩";
opt.imageUrl = "https://cdn.example.com/invite.png";
opt.query = "action=invite&userId=12345";
opt.success = [](wxwasmsdk::GeneralCallbackResult& res) {
std::cout << "分享成功" << std::endl;
};
wxwasmsdk::ShareAppMessage(opt);
}
# 激励视频广告
#include "wx.h"
class RewardedVideoAd {
public:
void Init(const std::string& adUnitId) {
wxwasmsdk::CreateRewardedVideoAdOption opt;
opt.adUnitId = adUnitId;
ad_ = wxwasmsdk::CreateRewardedVideoAd(opt);
// 监听广告加载
ad_->OnLoad([this]() {
std::cout << "广告加载完成" << std::endl;
is_loaded_ = true;
});
// 监听广告错误
ad_->OnError([](wxwasmsdk::RewardedVideoAdOnErrorListenerResult& res) {
std::cout << "广告加载失败: " << res.errMsg << std::endl;
});
// 监听广告关闭
ad_->OnClose([this](wxwasmsdk::RewardedVideoAdOnCloseListenerResult& res) {
if (res.isEnded) {
std::cout << "用户完整观看广告,发放奖励" << std::endl;
GiveReward();
} else {
std::cout << "用户提前关闭广告" << std::endl;
}
is_loaded_ = false;
});
}
void Show() {
if (is_loaded_) {
ad_->Show();
} else {
// 加载广告
ad_->Load();
}
}
private:
wxwasmsdk::RewardedVideoAd* ad_ = nullptr;
bool is_loaded_ = false;
void GiveReward() {
// 发放游戏奖励
}
};
# 云存档
#include "wx.h"
void SaveToCloud(const std::string& key, const std::string& value) {
wxwasmsdk::SetUserCloudStorageOption opt;
opt.KVDataList.push_back({key, value});
opt.success = [](wxwasmsdk::GeneralCallbackResult& res) {
std::cout << "云存档保存成功" << std::endl;
};
opt.fail = [](wxwasmsdk::GeneralCallbackResult& res) {
std::cout << "云存档保存失败: " << res.errMsg << std::endl;
};
wxwasmsdk::SetUserCloudStorage(opt);
}
void LoadFromCloud(const std::vector<std::string>& keys) {
wxwasmsdk::GetUserCloudStorageOption opt;
opt.keyList = keys;
opt.success = [](wxwasmsdk::GetUserCloudStorageSuccessCallbackResult& res) {
for (const auto& item : res.KVDataList) {
std::cout << item.key << ": " << item.value << std::endl;
}
};
wxwasmsdk::GetUserCloudStorage(opt);
}
# 虚拟支付
#include "wx.h"
void BuyItem(const std::string& itemId, int price) {
wxwasmsdk::RequestMidasPaymentOption opt;
opt.mode = "game";
opt.env = 0; // 0: 米大师正式环境
opt.offerId = "your-offer-id";
opt.currencyType = "CNY";
opt.platform = "android"; // 或 "ios"
opt.buyQuantity = price;
opt.success = [itemId](wxwasmsdk::GeneralCallbackResult& res) {
std::cout << "支付成功" << std::endl;
// 发放道具
GiveItem(itemId);
};
opt.fail = [](wxwasmsdk::GeneralCallbackResult& res) {
std::cout << "支付失败: " << res.errMsg << std::endl;
};
wxwasmsdk::RequestMidasPayment(opt);
}
# 封装类示例
#include "wx.h"
class WXPlatform {
public:
static WXPlatform& Instance() {
static WXPlatform instance;
return instance;
}
// 初始化
void Init() {
// 获取系统信息
auto sysInfo = wxwasmsdk::GetAppBaseInfo();
sdk_version_ = sysInfo.SDKVersion;
// 设置生命周期监听
SetupLifecycleListeners();
// 设置分享
SetupShare();
}
// 登录
void Login(std::function<void(const std::string& openid)> onSuccess,
std::function<void(const std::string& error)> onFail = nullptr) {
wxwasmsdk::LoginOption opt;
opt.timeout = 10000;
opt.success = [onSuccess, onFail, this](wxwasmsdk::LoginSuccessCallbackResult& res) {
// 向服务器换取 openid
ExchangeOpenId(res.code, onSuccess, onFail);
};
opt.fail = [onFail](wxwasmsdk::GeneralCallbackResult& res) {
if (onFail) onFail(res.errMsg);
};
wxwasmsdk::Login(opt);
}
// 分享
void Share(const std::string& title, const std::string& imageUrl,
const std::string& query = "") {
wxwasmsdk::ShareAppMessageOption opt;
opt.title = title;
opt.imageUrl = imageUrl;
opt.query = query;
wxwasmsdk::ShareAppMessage(opt);
}
// 显示广告
void ShowRewardedAd(std::function<void()> onRewarded) {
on_ad_rewarded_ = onRewarded;
if (rewarded_ad_ && ad_loaded_) {
rewarded_ad_->Show();
}
}
const std::string& GetSDKVersion() const { return sdk_version_; }
private:
void SetupLifecycleListeners() {
// ... 参考前面的示例
}
void SetupShare() {
// ... 参考前面的示例
}
void ExchangeOpenId(const std::string& code,
std::function<void(const std::string&)> onSuccess,
std::function<void(const std::string&)> onFail) {
// 发送到服务器换取 openid
// ...
}
std::string sdk_version_;
wxwasmsdk::RewardedVideoAd* rewarded_ad_ = nullptr;
bool ad_loaded_ = false;
std::function<void()> on_ad_rewarded_;
};
# 常见问题
# Q: 登录时报错"未开通XX权限"?
A: 检查小游戏是否已完成微信认证,并在后台开通相应权限。
# Q: 分享图片不显示?
A: 确保图片 URL 可访问,且图片尺寸符合要求(建议 5:4 比例)。
# Q: 支付失败?
A: 检查米大师配置是否正确,offerId 是否正确。
# 注意事项
- 真机测试:部分功能只能在真机上测试
- 审核合规:使用用户信息前需要获取用户授权
- 版本兼容:注意 API 的最低基础库版本要求
- 错误处理:始终处理 fail 回调