解决lua与C++交互问题一则,记一笔

CEGUI可以通过lua加载xml的窗口层.使用函数:loadWindowLayout, 这个函数的原型是这样的:

Window*    loadWindowLayout(const String& filename, const String& name_prefix = "", const String& resourceGroup = "", PropertyCallback* callback = 0, void* userdata = 0);

第一个参数是必须的,后面的都可以使用默认参数.

比如加载某一个窗口层的脚本如下:

WindowManager:getSingleton():loadWindowLayout("layout.xml");

这个时候如果这个layout.xml这个文件不在当前目录下,那么,就在要程序中动态配置它的目录,所以我就加了一个资源管理的类,负责所有资源的目录管理,给一个资源的名称(项目要求资源名称全局唯一),然后给出这个资源的完整名称(含有路径的名称):

C++函数原型如下:

std::string AssertProvider::GetFullname(const std::string &rscName);

这样写, 在C++项目中与lua中都可以使用,所以在lua中加载CEGUI的窗口层就要改成这样写了:

WindowManager:getSingleton():loadWindowLayout(
AssertProvider:getSingleton():GetFullname("layout.xml"));

但是在lua调用中(使用tolua++将C++转换成一个可在lua使用的类), 在这个lua调用, GetFullname()这个函数却返回了两个参数!!! 第一个是它的return值, 第二个参数是这个函数的参数!

这就有了问题.因为loadWindowLayout的第二个参数是窗口的名称的后缀名称, 在xml的cegui窗口布局中,很多都是使用的匿名窗口, 即,让cegui系统自动分配一个窗口名称, 当loadWindowLayout的第一个参数+第二个参数为一个空串时, cegui就会为窗口分配一个名称. 此时不是了, 因为这个函数的第二个参数被传入了一个非空的string, 在上面的示例代码中传入是:"layout.xml"这个字符串. 所以, 很多地方摄氏,说是无法创建窗口. 解决方式如下:将GetFullname()的参数由引用类型改为const char* 类型即可.这样,这个参数就只返回一个参数.