首页 > 代码库 > 将iconv编译成lua接口

将iconv编译成lua接口

前一篇博文说了,在cocos2dx中怎么样使用iconv转码,这节我们将上一节中写的转码函数,做成一个lua接口,在lua脚本中使用。


// luaiconv.h

#ifndef __LUA_ICONV_H__
#define __LUA_ICONV_H__


#include "tolua++.h"
#include "tolua_event.h"
#include "lauxlib.h"


#if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32
#include "iconv.h"
#elif CC_TARGET_PLATFORM == CC_PLATFORM_IOS
#include <iconv.h>
#elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID
#include "iconv.h"
#endif


int tolua_iconv_open(lua_State *L);


#endif


//luaiconv.cpp
#include "luaiconv.h"
#include <stdlib.h>


#define MAX_STRING_SIZE 1024
#define TEST_STR ("Hello, 这是个转码测试字符串")


bool iconv_convert(void *src, unsigned int src_len,char *src_charset, void *dest, unsigned int dest_len, char *dest_charset)
{
	const char *in;
	char *out,*dest_ptr;
	size_t in_left,out_left,mutant,converted;


	in_left = src_len;
	out_left = dest_len;
	in = (char *)src;
	out = dest_ptr = (char *)dest;


	iconv_t oConv=iconv_open(dest_charset,src_charset);
	if(oConv==(iconv_t)(-1)){
		printf("XXXXXXXXXX ERROR: unable to open libiconv.\n");
		return false;
	}


	mutant = iconv(oConv, &in, &in_left, &out, &out_left );
	iconv_close(oConv);


	if(mutant == (size_t)(-1)){
		printf("XXXXXXXXXX ERROR: unable to convert anything.\n");
		return false;
	}
	converted = dest_len - out_left;
	dest_ptr[converted]='\0';


	printf("XXXXXXXXXX src string:%s\n", src);
	printf("XXXXXXXXXX to convert %u characters, %u mutanted , %u converted \n",src_len,mutant,converted);
	printf("XXXXXXXXXX dst string:%s\n", dest);


	return true;
}


void convertTest()
{
	char inStr[] = TEST_STR;
	char outStr[MAX_STRING_SIZE];
	iconv_convert(&inStr, sizeof(inStr), "GBK", &outStr, sizeof(outStr), "UTF-8");
	printf("XXXXXXXXXX in string:%s\n", inStr);
	printf("XXXXXXXXXX out string:%s\n", outStr);
}


TOLUA_API int luaiconv(lua_State *L)
{	
	char *inbuf = (char*) luaL_checkstring(L, 1);
	char *src_charset = (char*) luaL_checkstring(L, 2);
	char *dst_charset = (char*) luaL_checkstring(L, 3);


	size_t ibleft = lua_strlen(L, 1);
	size_t obleft = (ibleft > 256) ? ibleft : 256; 
	char *outbuf = (char*) malloc(obleft * sizeof(char));
    if (outbuf == NULL) {
        lua_pushstring(L, "");
        return 1;
    }
	
	if(!iconv_convert(inbuf, ibleft, src_charset, outbuf, obleft, dst_charset)){
		lua_pushstring(L, "");
		return 1;
	}
	
    lua_pushstring(L, outbuf);
    free(outbuf);
	
    return 1;
}


static luaL_Reg iconvlib[] = {
	{"luaiconv", luaiconv},
	{NULL, NULL}
};


// 函数名必须为luaopen_xxx,其中xxx表示library名称,Lua代码require "xxx"需要与之对应。
int luaopen_iconv(lua_State* L)
{
	const char* libName = "iconv";
	luaL_register(L, libName, iconvlib);// 调用方式libName.函数名


	return 1;
}


int tolua_iconv_open(lua_State *L)
{	
	luaopen_iconv(L);
	return 1;
}


在AppDelegate中

#include "luaiconv.h"



然后在AppDelegate::applicationDidFinishLaunching()中调用:

CCLuaEngine* pEngine = CCLuaEngine::defaultEngine();
CCScriptEngineManager::sharedManager()->setScriptEngine(pEngine);
tolua_iconv_open(pEngine->getLuaStack()->getLuaState());


在lua中这样使用:
require "iconv"
iconv.luaiconv("string to convert code","GBK","UTF-8")


将iconv编译成lua接口