iOS端游戏 OC C++ lua脚本交互
iOS端手游,iOS工程师需要做的是sdk开发和游戏lua脚本的交互。我就拿原生分享接口为例子。写一下自己在OC 和C++ 和lua脚本之间的交互逻辑。包括lua脚本注册,lua-》c++ =》oc的交互。
首先就是创建C++文件,用来做OC和C++的bridge。
AoKiShareNative.hpp
#ifndef AoKiShareNative_hpp
#define AoKiShareNative_hpp
#include <stdio.h>
#include <string>
#include <map>
#include <vector>
#include <list>
class AoKiShareNative {
public:
static AoKiShareNative* getInstance();
/**
分享二进制图片
param type 类型0 = 微信好友 1 = 微信朋友圈 2 = qq好友 3 = 微博
param title 标题
param imageData 图片二进制 <10MB
param intro 内容
*/
static void shareImageFilePath(std::string type, std::string title, std::string imageFilePath, std::string intro);
/**
分享图片链接
param type 类型0 = 微信好友 1 = 微信朋友圈 2 = qq好友 3 = 微博
param title 标题
param imageUrl 图片链接
param intro 内容
*/
static void shareImageUrl(std::string type, std::string title, std::string imageUrl, std::string intro);
/**
分享缩略图 + 链接
param type 类型0 = 微信好友 1 = 微信朋友圈 2 = qq好友 3 = 微博
param title 标题
param imageData 图片二进制
param intro 内容
param url 链接
*/
static void shareWeb(std::string type, std::string title, std::string imageFilePath, std::string intro, std::string url);
/**
分享文字
param type 类型0 = 微信好友 1 = 微信朋友圈 2 = qq好友 3 = 微博
param intro 内容
*/
static void shareText(std::string type, std::string intro);
/**
获取分享渠道列表
*/
static std::vector<std::string> getShareChannelArr();
private:
static AoKiShareNative* instance;
};
#endif /* AoKiShareNative_hpp */
AoKiShareNative.mm
#include "AoKiShareNative.hpp"
#import "AoJiaoShareManager.h"
#include "platform/CCFileUtils.h"
AoKiShareNative* AoKiShareNative::instance = NULL;
AoKiShareNative* AoKiShareNative::getInstance() {
if (instance == NULL) {
instance = new AoKiShareNative();
}
return instance;
}
void AoKiShareNative::shareImageFilePath(std::string type, std::string title, std::string imageFilePath, std::string intro){
NSString *imageStr = [NSString stringWithUTF8String:imageFilePath.c_str()];
if (![[NSString stringWithUTF8String:imageFilePath.c_str()] containsString:@"http"]) {
auto fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(imageFilePath);
imageStr = [NSString stringWithUTF8String:fullPath.c_str()];
}
[[AoJiaoShareManager sharedInstance] shareImagePathWithType:[NSString stringWithUTF8String:type.c_str()] title:[NSString stringWithUTF8String:title.c_str()] imageFilePath:imageStr intro:[NSString stringWithUTF8String:intro.c_str()]];
}
/**
分享图片链接
param type 类型0 = 微信好友 1 = 微信朋友圈 2 = qq好友 3 = 微博
param title 标题
param imageUrl 图片链接
param intro 内容
*/
void AoKiShareNative::shareImageUrl(std::string type, std::string title, std::string imageUrl, std::string intro){
[[AoJiaoShareManager sharedInstance] shareImageUrlWithType:[NSString stringWithUTF8String:type.c_str()] title:[NSString stringWithUTF8String:title.c_str()] imageUrl:[NSString stringWithUTF8String:imageUrl.c_str()] intro:[NSString stringWithUTF8String:intro.c_str()]];
}
/**
分享缩略图 + 链接
param type 类型0 = 微信好友 1 = 微信朋友圈 2 = qq好友 3 = 微博
param title 标题
param imageData 图片二进制
param intro 内容
param url 链接
*/
void AoKiShareNative::shareWeb(std::string type, std::string title, std::string imageFilePath, std::string intro, std::string url){
NSString *imageStr = [NSString stringWithUTF8String:imageFilePath.c_str()];
if (![[NSString stringWithUTF8String:imageFilePath.c_str()] containsString:@"http"]) {
auto fullPath = cocos2d::FileUtils::getInstance()->fullPathForFilename(imageFilePath);
imageStr = [NSString stringWithUTF8String:fullPath.c_str()];
}
[[AoJiaoShareManager sharedInstance] shareWebWithType:[NSString stringWithUTF8String:type.c_str()]
title:[NSString stringWithUTF8String:title.c_str()]
imageFilePath:imageStr
intro:[NSString stringWithUTF8String:intro.c_str()]
url:[NSString stringWithUTF8String:url.c_str()]];
}
/**
分享文字
param type 类型0 = 微信好友 1 = 微信朋友圈 2 = qq好友 3 = 微博
param intro 内容
*/
void AoKiShareNative::shareText(std::string type, std::string intro){
[[AoJiaoShareManager sharedInstance] shareTextWithType:[NSString stringWithUTF8String:type.c_str()] intro:[NSString stringWithUTF8String:intro.c_str()]];
}
/**
获取分享渠道列表
*/
std::vector<std::string> AoKiShareNative::getShareChannelArr(){
NSArray *shareArr = [[AoJiaoShareManager sharedInstance] getShareChannelArr];
std::vector<std::string> vector;
for(int i =0; i< shareArr.count; i++){
std::string str = [[shareArr objectAtIndex:i] UTF8String];
vector.push_back(str);
}
return vector;
}
重点来了,下面是luabinding文件,包括注册luabinding,注册lua函数以供游戏调用。
share_lua_binding.hpp
#ifndef share_lua_binding_hpp
#define share_lua_binding_hpp
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "tolua++.h"
#ifdef __cplusplus
}
#endif
TOLUA_API int register_share_luabinding(lua_State* L);
#endif /* share_lua_binding_hpp */
share_lua_binding.cpp
#include "share_lua_binding.hpp"
#include "AoKiShareNative.hpp"
#include "tolua_fix.h"
#include "LuaBasicConversions.h"
#include "CCLuaEngine.h"
int lua_fysdk_shareText(lua_State* toluaS) {
if (lua_gettop(toluaS) < 2 || !lua_isstring(toluaS, 1) || !lua_isstring(toluaS, 2) ) {
CCLOG("Wrong Args For shareText");
return 0;
}
std::string type = tolua_tocppstring(toluaS, 1, "");
std::string intro = tolua_tocppstring(toluaS, 2, "");
AoKiShareNative::getInstance()->shareText(type, intro);
return 0;
}
int lua_fysdk_shareWeb(lua_State* toluaS) {
if (lua_gettop(toluaS) < 5 || !lua_isstring(toluaS, 1) || !lua_isstring(toluaS, 2)
|| !lua_isstring(toluaS, 3) || !lua_isstring(toluaS, 4) || !lua_isstring(toluaS, 5)) {
CCLOG("Wrong Args For shareText");
return 0;
}
std::string type = tolua_tocppstring(toluaS, 1, "");
std::string title = tolua_tocppstring(toluaS, 2, "");
std::string imageFilePath = tolua_tocppstring(toluaS, 3, "");
std::string intro = tolua_tocppstring(toluaS, 4, "");
std::string url = tolua_tocppstring(toluaS, 5, "");
AoKiShareNative::getInstance()->shareWeb(type, title, imageFilePath, intro, url);
return 0;
}
int lua_fysdk_shareImageUrl(lua_State* toluaS) {
if (lua_gettop(toluaS) < 4 || !lua_isstring(toluaS, 1) || !lua_isstring(toluaS, 2)
|| !lua_isstring(toluaS, 3) || !lua_isstring(toluaS, 4)) {
CCLOG("Wrong Args For shareText");
return 0;
}
std::string type = tolua_tocppstring(toluaS, 1, "");
std::string title = tolua_tocppstring(toluaS, 2, "");
std::string imageUrl = tolua_tocppstring(toluaS, 3, "");
std::string intro = tolua_tocppstring(toluaS, 4, "");
AoKiShareNative::getInstance()->shareImageUrl(type, title, imageUrl, intro);
return 0;
}
int lua_fysdk_shareImageFilePath(lua_State* toluaS) {
if (lua_gettop(toluaS) < 4 || !lua_isstring(toluaS, 1) || !lua_isstring(toluaS, 2)
|| !lua_isstring(toluaS, 3) || !lua_isstring(toluaS, 4)) {
CCLOG("Wrong Args For shareText");
return 0;
}
std::string type = tolua_tocppstring(toluaS, 1, "");
std::string title = tolua_tocppstring(toluaS, 2, "");
std::string imageFilePath = tolua_tocppstring(toluaS, 3, "");
std::string intro = tolua_tocppstring(toluaS, 4, "");
AoKiShareNative::getInstance()->shareImageFilePath(type, title, imageFilePath, intro);
return 0;
}
int lua_fysdk_getShareChannelArr(lua_State* toluaS) {
std::vector<std::string> shareList = AoKiShareNative::getInstance()->getShareChannelArr();
lua_newtable(toluaS);
for (int i = 0; i < shareList.size(); i++) {
std::string channel = shareList.at(i);
lua_pushstring(toluaS, channel.c_str());
lua_pushboolean(toluaS, true);
lua_settable(toluaS, -3);
}
return 1;
}
static const struct luaL_Reg share_funcs[] = {
{"shareText",lua_fysdk_shareText},
{"shareWeb",lua_fysdk_shareWeb},
{"shareImageUrl",lua_fysdk_shareImageUrl},
{"shareImageFilePath",lua_fysdk_shareImageFilePath},
{"getShareChannelArr",lua_fysdk_getShareChannelArr},
{NULL, NULL},
};
int lua_share_sdk_bridge(lua_State* toluaS) {
lua_newtable(toluaS);
lua_pushvalue(toluaS, -1);
lua_setfield(toluaS, LUA_GLOBALSINDEX, "AOKIShare");
const luaL_Reg* lib = share_funcs;
for (; lib->func; lib++) {
lua_pushcfunction(toluaS, lib->func);
lua_setfield(toluaS, -2, lib->name);
}
lua_newtable(toluaS);
lua_pop(toluaS, 1);
return 0;
}
int register_share_luabinding(lua_State* toluaS) {
return lua_share_sdk_bridge(toluaS);
}
然后去AppDelegate.cpp(游戏的主程序)文件里注册 register_share_luabinding方法。
AppDelegate.cpp
#include "share_lua_binding.hpp"
bool AppDelegate::applicationStartGame()
{
auto engine = LuaEngine::getInstance();
register_share_luabinding(engine->getLuaStack()->getLuaState());
}
最后是游戏lua脚本调用,首先是appinit.lua注册share_bridge.lua文件
appinit.lua
ShareManager = require "controller.share_bridge"
share_bridge.lua
local sharebridge = {}
function sharebridge.shareText(type, intro)
return AOKIShare.shareText(type, intro)
end
function sharebridge.shareWeb(type, title, imageFilePath, intro, url)
return AOKIShare.shareWeb(type, title, imageFilePath, intro, url)
end
function sharebridge.shareImageUrl(type, title, imageUrl, intro)
return AOKIShare.shareImageUrl(type, title, imageUrl, intro)
end
function sharebridge.shareImageFilePath(type, title, imageFilePath, intro)
return AOKIShare.shareImageFilePath(type, title, imageFilePath, intro)
end
function sharebridge.getShareChannelArr()
return AOKIShare.getShareChannelArr()
end
return sharebridge
调用分享方法
print(dump(ShareManager.getShareChannelArr()))
ShareManager.shareText("0", "魂器分享")
以上。