游戏开发论坛

 找回密码
 立即注册
搜索
查看: 6345|回复: 7

CEGUI + LUA的一个吐血问题,已头疼两天+

[复制链接]

5

主题

18

帖子

22

积分

注册会员

Rank: 2

积分
22
发表于 2009-8-5 19:52:00 | 显示全部楼层 |阅读模式
为CEGUI配置中文字体后,使用C++调用和操作CEGUI,中文能够正常的处理和显示

例如:

Editbox * editbox = static_cast<Editbox*>(m_WinMgr.getWindow("Demo8/Window1/Controls/Editbox"));
Listbox * listbox = static_cast<Listbox*>(m_WinMgr.getWindow("Demo8/Window1/Listbox"));
           
CEGUI::String edit_str(editbox->getText());
       
ListboxTextItem* tempItem = new ListboxTextItem(edit_str);
listbox->addItem(tempItem);
       
testText->setText(mbcs_to_utf8((const char*)"中文测试"));

等等均可以正确的获取到控件上输入的中文,并设置给其它控件等.


但是将逻辑移到lua中,中文就完全不能处理了

例如:

local editbox = winMgr:getWindow("Demo8/Window1/Controls/Editbox")
local listbox = CEGUI.toListbox(winMgr:getWindow("Demo8/Window1/Listbox"))
local addbutton = winMgr:getWindow("Demo8/Window1/Controls/Add")
       
addbutton:setText(editbox:getText())
       
print(editbox:getText())
       
CEGUI.Logger:getSingleton():logEvent(editbox:getText())
       
local newItem = CEGUI.createListboxTextItem(editbox:getText())
       
listbox:addItem(newItem)

将全部得到乱码

getText()得到的 能正常显示在控件上的中文 ,用于输出,记log,或者设置给其它控件,均显示的是乱码.

而在lua中单纯写入的中文可以正常显示

print("中文测试")       --正常

CEGUI.Logger:getSingleton():logEvent("中文测试")    --乱码


print是lua自己的东西,如果这样都出乱码,那lua也不用玩了-_-

以上现象分析: lua与cegui的编码格式可能不同,lua与cegui交互,从cegui获得的中文字符串,或传给cegui的中文字符串,两方均不能正常解析,彼此都认不出,都为乱码.

尝试在lua中将中文字符串编码方式转换后再发送给cegui,  lua的字符串编码, 要么为ascii,要么为unicode
cegui::string的编码方式, 目前已知的有,接收utf8的构造函数

所以,写了N个编码转换函数进行尝试
AsciiToUnicode , AsciiToUtf8 , unicodeToUtf8 , ..............
(均进行了测试,转换正确)

然后将这些函数导入到lua中

EditBox:setText(AsciiToUnicode(str))
EditBox:setText(AsciiToUtf8(str))
EditBox:setText(unicodeToUtf8(str))

几乎常用的所有编码能试的全试了,结果只是乱码更乱....

求高手指点..万分感谢

如果回帖说不清..QQ67997876, 或者发个电话号码我打电话过去

lua与cegui之间究竟发生了什么,它们之间有着怎样不可告人的秘密?

5

主题

18

帖子

22

积分

注册会员

Rank: 2

积分
22
 楼主| 发表于 2009-8-5 23:31:00 | 显示全部楼层

Re:CEGUI + LUA的一个吐血问题,已头疼两天+

"问题在于,在lua实现gettext函数的时候,把得到的字符串从CEGUI::string转化成了char* 类型,导致了中文格式的不符。在后面创建item以及additem后无法显示"

在网上搜到了这句话

那么,在lua中直接setText("中文测试"),没能显示出中文,应该是lua文件不是utf8格式的导致的

而getText得到的中文,相当于str = (char *)CEGUI::String.c_str(), 直接取到了CEGUI::String的buffer, 这个buffer是以utf8编码的, 在lua中,将此buffer作为char *显示,结果导致乱码

照这样分析,就应该把这个buffer转换为unicode,或者ascii来显示, 那么需要的转换函数就是utf8ToAscii

不知道这样分析的对不对.....

5

主题

18

帖子

22

积分

注册会员

Rank: 2

积分
22
 楼主| 发表于 2009-8-6 15:09:00 | 显示全部楼层

Re:CEGUI + LUA的一个吐血问题,已头疼两天+

自己顶一下。。。

0

主题

2

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2009-8-18 15:43:00 | 显示全部楼层

Re:CEGUI + LUA的一个吐血问题,已头疼两天+

这么些天不知道楼主搞定了没有。
主要问题还是出在CEGui::String这个结构体,他有一个接受CEGui::utf8*的构造函数,如果要用中文,就必须用这个构造函数初始化一个string,再传到Window::setText中去,比如我们在c++里这样写:
const char* tx = WindowManager::getSingleton().getWindow("Demo8/Window1/Controls/Add")->getText().c_str();//"Demo8/Window1/Controls/Add"这个的text是中文
WindowManager::getSingleton().getWindow("Demo8/Window2/Info")->setText(tx);
这样还是乱码,要强制转换成utf8*,写成:
WindowManager::getSingleton().getWindow("Demo8/Window2/Info")->setText((utf8*)tx);

但是lua调用cegui的时候(我这里假设你用的是cegui附带的LuaScriptModule),并没有加入转换utf8*这步,所以从lua中的char传到setText函数时,调用到的CEGui::String构造函数并不是带有utf8*参数的那个,如果在debug调试环境下,可以看到他的d_cplength在utf8*构造函数下是等于中文字数的,如果是char*构造函数下是中文字数*3的(或者是??)。

解决方案一:就是修改CEGUILua.lib的源文件,并重新编译一个新的库,但是关联函数是用tolua++自动生成的,改了不知道会引起其他什么问题,如果要改,在lua_cegui.cpp的15326行将后面那个(string)改成(utf*),我没试过。
解决方案二:封装一层setText函数,重新导出给lua,在新的setText函数里面先转换成utf8*再传给真正的setText。这个方案比较安全。

0

主题

2

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2009-8-18 16:07:00 | 显示全部楼层

Re:CEGUI + LUA的一个吐血问题,已头疼两天+

根据第二种方案,我自己写了个函数导出给lua,用到了tolua++里的函数,或者你自己包:

static int mySetText(lua_State* luaVM)
{
        using namespace CEGUI;
        const char* wd = tolua_tocppstring(luaVM, 1, 0);
        const char* tx = tolua_tocppstring(luaVM, 2, 0);

        WindowManager::getSingleton().getWindow(wd)->setText((utf8*)tx);
        return 1;
}

然后在主函数里注册他:
        LuaScriptModule* scriptmod = new LuaScriptModule();
        lua_register( scriptmod->getLuaState(), "mysetText", (lua_CFunction)mySetText );


然后在lua中调用:
--"Demo8/Window1"的text是中文
tx = winMgr:getWindow("Demo8/Window1"):getText()
mysetText("Demo8/Window2/Info", tx)
就可以在"Demo8/Window2/Info"这个window里正常显示中文了。

1

主题

2

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2009-11-3 16:35:00 | 显示全部楼层

Re:CEGUI + LUA的一个吐血问题,已头疼两天+

我修改了CEGUI::String的三个函数,然后就没问题了。
C++调用时也不需要在外面进行编码转换。lua也没问题。

具体的内容在这里:
http://topic.csdn.net/u/20090805/20/4bdadcc7-69fd-443e-b5b8-044bc652a89d.html

4

主题

19

帖子

19

积分

新手上路

Rank: 1

积分
19
发表于 2010-7-22 15:37:00 | 显示全部楼层

Re: CEGUI + LUA的一个吐血问题,已头疼两天+

最终和最简单的方法。。只改一个函数。(CEGUI0.7.1)

将 tolua++.h 中的。。函数:  

static inline const char* tolua_tocppstring (lua_State* L, int narg, const char* def) {

        const char* s = tolua_tostring(L, narg, def);
        return s?s:"";
}

改为:  
static inline const unsigned char* tolua_tocppstring (lua_State* L, int narg, const char* def) {

        const unsigned char* s = (const unsigned char*)tolua_tostring(L, narg, def);
        return s?sconst unsigned char*)("");
}

主要理由如下:

cegui中的utf8*类型为unsigned char*...。。lua文件以utf8无符号的格式,即可。。

3

主题

263

帖子

267

积分

中级会员

Rank: 3Rank: 3

积分
267
发表于 2010-7-22 22:16:00 | 显示全部楼层

Re:CEGUI + LUA的一个吐血问题,已头疼两天+

呵呵,楼上们的说的对,我就不多说了,帮顶~
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-8 08:07

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表