1. 程式人生 > >Cocos2d-x中用Lua實現剪下板的文字複製貼上(iOS篇)

Cocos2d-x中用Lua實現剪下板的文字複製貼上(iOS篇)

個問題搞死我了……弄了好久才弄好。看上去其實挺唬人的,需要從Lua調到C++,再調到OC,其實仔細分析一下的話還好。我們下面開始講解:

首先是Lua調到C++(如果直接是C++的專案請無視):
首先,我們在專案裡建一個ClipboardHelper.cpp,一個ClipboardHelper.hpp(.h的也可)。


.hpp中我們宣告一個想讓Lua呼叫的函式:

#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","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;
}
好,基本完成,我們只要在AppDelegate.cpp中引用一下lua_MyToLua_auto.hpp:
#include "lua_MyToLua_auto.hpp"
然後我們再在AppDelegate.cpp中找到 AppDelegate::applicationDidFinishLaunching()這個函式,在其中新增:
register_all_MyToLua(L);

加的位置也要稍微注意一下,不要太無腦的塞進去……


大功告成,我們只要在Lua中寫一句程式碼:

ClipboardHelper:copyLua(str)
其中str是你要複製的文字,看看控制檯,是不是輸出出來了呢?

好,Lua調C++成功搞定,下面重頭戲來了:

用C++調OC。

看起來很難?其實並不。

首先我們來建一個OC檔案,副檔名為.m,然後再建一個與它名字相同的.h檔案。

重點來了,我們把.m檔案的副檔名改為.mm,這樣的話它就會變成一個C++與OC的混編檔案,使C++可以呼叫到他。

現在.h程式碼如下:

#include <stdio.h>
#include "cocos2d.h"

class iOSClipboard {
    
public:
    static void copy(std::string str);
};

.mm中這樣實現:
#include "iOSClipboard.h"
#import <Foundation/Foundation.h>

void iOSClipboard::copy(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;
}

好了,現在我們可以通過剛剛寫的ClipboardHelper.cpp中引入iOSClipboard.h標頭檔案,然後呼叫copy方法實現呼叫OC了。

當然,在這裡還可以加入更多的方法,來實現C++呼叫OC