这个问题搞死我了……弄了好久才弄好。看上去其实挺唬人的,需要从Lua调到C++,再调到OC,其实仔细分析一下的话还好。我们下面开始讲解:
首先是Lua调到C++(如果直接是C++的项目请无视):首先,我们在项目里建一个ClipboardHelper.cpp,一个ClipboardHelper.hpp(.h的也可)。
#ifndef ClipboardHelper_hpp #define ClipboardHelper_hpp #include <stdio.h> #include "cocos2d.h" class ClipboardHelper { public: void copyLua(std::string str); }; #endif /* ClipboardHelper_hpp */
.cpp中的实现:
#include "ClipboardHelper.hpp" #include "CCLuaEngine.h" void ClipboardHelper::copyLua(std::string str) { CCLOG("%s",str.c_str()); }在这一步里我们不需要做些什么实质的事情,因为一会儿我们需要在这里调OC。这一步先不涉及。先让Lua能成功调到C++再说。
下面我们再新建两个文件:lua_MyToLua_auto.cpp 和lua_MyToLua_auto.hpp
这两个文件是用来给Lua注册我们刚刚写的那个函数的。lua_MyToLua_auto.hpp中的代码:
#include "base/ccConfig.h" #ifndef __MyToLua_h__ #define __MyToLua_h__ #ifdef __cplusplus extern "C" { #endif #include "tolua++.h" #ifdef __cplusplus } #endif int register_all_MyToLua(lua_State* tolua_S); #endif // __MyToLua_h__
lua_MyToLua_auto.cpp中我们需要注册刚刚写的那个函数 以下是代码:
#include "lua_MyToLua_auto.hpp" #include "ClipboardHelper.hpp" #include "tolua_fix.h" #include "LuaBasicConversions.h" int lua_register_MyToLua_ClipboardHelper(lua_State* tolua_S){ tolua_usertype(tolua_S,"ClipboardHelper"); tolua_cclass(tolua_S,"ClipboardHelper","",nullptr); tolua_beginmodule(tolua_S,"ClipboardHelper"); tolua_function(tolua_S,"copyLua",lua_MyTolua_ClipboardHelper_copyLua); tolua_endmodule(tolua_S); std::string typeName = typeid(ClipboardHelper).name(); g_luaType[typeName] = "ClipboardHelper"; g_typeCast["ClipboardHelper"] = "ClipboardHelper"; return 1; } int lua_MyTolua_ClipboardHelper_copyLua(lua_State* tolua_S) { int argc = 0; ClipboardHelper* cobj = nullptr; bool ok = true; #if COCOS2D_DEBUG >= 1 tolua_Error tolua_err; #endif argc = lua_gettop(tolua_S)-1; if (argc == 1) { std::string arg0; ok &= luaval_to_std_string(tolua_S,2,(std::string *)&arg0,"ClipboardHelper:copyLua"); if(!ok) { tolua_error(tolua_S,"invalid arguments in function 'lua_MyToLua_ClipboardHelper_copyLua'",nullptr); return 0; } cobj->copyLua(arg0); lua_settop(tolua_S,1); return 1; } luaL_error(tolua_S,"%s has wrong number of arguments: %d,was expecting %d \n","ClipboardHelper:ClipboardHelper",argc,1); return 0; #if COCOS2D_DEBUG >= 1 tolua_error(tolua_S,"#ferror in function 'lua_MyToLua_ClipboardHelper_copyLua'.",&tolua_err); #endif return 0; } TOLUA_API int register_all_MyToLua(lua_State* tolua_S) { tolua_open(tolua_S); tolua_module(tolua_S,nullptr,0); tolua_beginmodule(tolua_S,nullptr); lua_register_MyToLua_ClipboardHelper(tolua_S); tolua_endmodule(tolua_S); return 1; }
#include "lua_MyToLua_auto.hpp"然后我们再在AppDelegate.cpp中找到 AppDelegate ::applicationDidFinishLaunching()这个函数,在其中添加:
register_all_MyToLua(L);
加的位置也要稍微注意一下,不要太无脑的塞进去……
大功告成,我们只要在Lua中写一句代码:
ClipboardHelper:copyLua(str)
好,Lua调C++成功搞定,下面重头戏来了:
用C++调OC。
看起来很难?其实并不。
首先,我们把刚刚建的ClipboardHelper.cpp重命名为ClipboardHelper.mm(注意改名之后在Xcode工程中需要重新导入一下)
.mm是C++和Objective-C的混编文件,里面既有C++的代码,也有OC的代码。
我们把刚刚写好copyLua方法的实现改一下,里面让他调用OC:
void ClipboardHelper::copyLua(std::string str) { //把string类型转换成为char* char*p=(char*)str.data(); //把char*转换成OC的NSString NSString *nsMessage= [[NSString alloc] initWithCString:p encoding:NSUTF8StringEncoding]; //获得iOS的剪切板 UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; //改变剪切板的内容 pasteboard.string = nsMessage; }是不是非常简单?快运行一下测测吧。