tolua编译
‘壹’ tolua 怎么bind std:vector
我在尝试导出Ogre的所有类接口到lua中使用,参考CEGUI的方法,使用的是tolua++来导出C++类对象。在使用过程中,遇到了一些问题。 问题1: 表现为tolua++编译错误,错误信息是:***curr code for error is $pfile "OgreBase/OgreVector2.h" 这里...
‘贰’ LUA编译好了,但是tolua++编译不出来出现以下错误
设置头文件包含目录。makefile里面用-I ,如果是ide,一般都有可以图形化选择的。
‘叁’ 有没有类似的tolua++工具导出c#引用c++的接口
我在尝试导出Ogre的所有类接口到lua中使用,参考CEGUI的方法,使用的是tolua++来导出C++类对象。在使用过程中,遇到了一些问题。
问题1:
表现为tolua++编译错误,错误信息是:***curr code for error is $pfile "OgreBase/OgreVector2.h"
这里我编写了一个OgreBase.pkg文件(给tolua++用来生成导出导入lua的定义文件)
namespace Ogre
{
$pfile "OgreBase/OgreSharedPtr.h"
$pfile "OgreBase/OgreVector2.h"
};
OgreSharedPtr.h文件内容如下:
$#include "OgreSharedPtr.h"
/// The method to use to free memory on destruction
enum SharedPtrFreeMethod
{
/// Use OGRE_DELETE to free the memory
SPFM_DELETE,
/// Use OGRE_DELETE_T to free (only MEMCATEGORY_GENERAL supported)
SPFM_DELETE_T,
/// Use OGRE_FREE to free (only MEMCATEGORY_GENERAL supported)
SPFM_FREE
};
class SharedPtr
{
TOLUA_TEMPLATE_BIND(T, Ogre::DataStream , Ogre::DataStreamList , Ogre::StringVector , Ogre::FileInfoList)
SharedPtr();
~SharedPtr();
T* get() ;
void bind(T* rep, SharedPtrFreeMethod freeMethod = SPFM_DELETE);
bool unique() ;
unsigned int useCount() ;
T* getPointer() ;
bool isNull(void) ;
void setNull(void);
};
OgreVector2.h内容如下:
$#include "OgreVector2.h"
class Vector2
{
public:
Real x, y;
public:
inline Vector2();
inline Vector2( Real fX, Real fY );
inline Vector2( Vector2& rkVector );
inline Real operator [] ( size_t i ) ;
inline Real& operator [] ( size_t i );
inline Real* ptr();
inline Real* ptr() ;
inline Vector2& operator = ( Vector2& rkVector );
inline Vector2& operator = ( Real fScalar);
inline bool operator == ( Vector2& rkVector ) ;
inline bool operator != ( Vector2& rkVector ) ;
inline Vector2 operator + ( Vector2& rkVector ) ;
inline Vector2 operator - ( Vector2& rkVector ) ;
inline Vector2 operator * ( Real fScalar ) ;
inline Vector2 operator * ( Vector2& rhs) ;
inline Vector2 operator / ( Real fScalar ) ;
inline Vector2 operator / ( Vector2& rhs) ;
inline Vector2& operator + () ;
inline Vector2 operator - () ;
inline Real length () ;
inline Real squaredLength () ;
inline Real dotProct( Vector2& vec) ;
inline Real normalise();
inline Vector2 midPoint( Vector2& vec ) ;
inline bool operator < ( Vector2& rhs ) ;
inline bool operator > ( Vector2& rhs ) ;
inline void makeFloor( Vector2& cmp );
inline void makeCeil( Vector2& cmp );
inline Vector2 perpendicular(void) ;
inline Real crossProct( Vector2& rkVector ) ;
inline Vector2 randomDeviant(
Real angle) ;
inline bool isZeroLength(void) ;
inline Vector2 normalisedCopy(void) ;
inline Vector2 reflect( Vector2& normal) ;
// special points
static const Vector2 ZERO;
static const Vector2 UNIT_X;
static const Vector2 UNIT_Y;
static const Vector2 NEGATIVE_UNIT_X;
static const Vector2 NEGATIVE_UNIT_Y;
static const Vector2 UNIT_SCALE;
};
咋一看,没任何问题,但是编译却错误。原因在于tolua++对$pfile的处理有些许问题,它是直接把被包含文件粘贴到一个文件中,而OgreSharedPtr.h最后一行是};,结果};和$pfile "OgreBase/OgreVector2.h"连在一行中了,结果出现编译错误。解决办法很简单,在每行$pfile之后加一行空行,或者在每个被包含头文件后保证最后一行是空行即可。
问题2:
tolua++对嵌套类模板的导出bug。编写如下的pkg文件,为了导出一个有4个模板参数的std::map类到lua中,而4个模板参数中有个模板参数Ogre::STLAllocator带有自身的模板参数嵌套,代码如下:
namespace Ogre
{
class STLAllocator
{
TOLUA_TEMPLATE_BIND(T, int , short, double, VECTOR3, std::string, IModelViewWrapper*, IDisplaySetting::Property, IDisplaySetting::DisplaySize, IDisplaySetting::AntiAliasingLevel, DataStreamPtr, Plane, PlaneBoundedVolume, Polygon*, std::pair<std::string Ogre::BaseResourceGroupManager::ArchiveIndexEntry>, std::pair<std::string Ogre::BaseResourceGroupManager::BaseResourceGroup*>, Ogre::BaseResourceGroupManager::ResourceLocation*)
};
};
namespace std
{
class less
{
TOLUA_TEMPLATE_BIND(T,std::string)
};
class pair
{
TOLUA_TEMPLATE_BIND(F S,std::string Ogre::BaseResourceGroupManager::ArchiveIndexEntry)
pair();
~pair();
F first;
S second;
};
class map
{
TOLUA_TEMPLATE_BIND(K V S A,std::string Ogre::BaseResourceGroupManager::ArchiveIndexEntry std::less<std::string> Ogre::STLAllocator<std::pair<std::string,Ogre::BaseResourceGroupManager::ArchiveIndexEntry> >)
class iterator
{
pair<K,V> operator->();
};
void clear();
bool empty();
int size() ;
std::map<K,V,S,A>::iterator find( K &key);
std::map<K,V,S,A>::iterator begin();
std::map<K,V,S,A>::iterator end();
std::map<K,V,S,A>::reverse_iterator rbegin();
std::map<K,V,S,A>::reverse_iterator rend();
std::pair<std::map<K,V,S,A>::iterator,bool> insert( std::pair<K,V> &value);
std::map<K,V,S,A>::iterator erase(std::map<K,V,S,A>::iterator iter);
map();
~map();
};
};
用tolua++编译这个pkg文件,生成cpp文件时不会出错,但编译cpp文件时会出错,因为它生成的cpp文件中,模板嵌套的代码有问题,如下:
生成的错误代码片段1:
std::map<std::string ,Ogre::BaseResourceGroupManager::ArchiveIndexEntry ,std::less<std::string> ,Ogre::STLAllocator<std::pair<std::string,Ogre::BaseResourceGroupManager::ArchiveIndexEntry> >>
生成的错误代码片段2:
std::map<std::string ,Ogre::BaseResourceGroupManager::ArchiveIndexEntry ,std::less<std::string> ,Ogre::STLAllocator<std::pair<std::string,Ogre::BaseResourceGroupManager::ArchiveIndexEntry> >,>
这两段错误代码中,第一个代码片段最后两个尖括号连接在一起了,错误在于最后两个尖括号间没有空格。
第二个代码片段最后两个尖括号间多了个“,”符号。
检查发现,是tolua++代码本身有bug,修复如下:
打开tolua++目录的lua目录,打开class.lua文件,181行append = string.gsub(append, ">>", "> >"),这里目的是把两个尖括号间加空格,但它没考虑到把这个类型与另一个模板类型嵌套使用的情况,结果出现代码片段1的bug,解决办法是改成append = string.gsub(append, ">>", "> > "),即在最后一个尖括号后自动加一个空格,以解决此问题,187行也有同样的问题,改成bI = string.gsub(bI, ">>", "> > ")即可。
对于错误的代码片段2,需要打开declaration.lua,定位到148行,改成local template_part = "<"..concat(m, 1, m.n , ",")..">",这样就能解决代码片段2的问题,此问题的起因在于此地方用空格来做模板参数的分隔符,但模板尖括号间又有空格,结果把这个空格自动替换成逗号,导致编译错误。
‘肆’ lua 怎么被c++调用的,或者怎么调用c++的
添加lua的头文件:
extern "C"
{
#include "./src/lua.h"
#include "./src/lualib.h"
#include "./src/lauxlib.h"}lua_State *lua = NULL; // 定义一个全局的lua_State指针 // 加载lua库lua = ::lua_open();
if (lua)
{
::luaopen_base(lua);
::luaopen_debug(lua);
::luaopen_math(lua);
::luaopen_string(lua);
::luaopen_table(lua);
} // 从lua脚本文件中获取函数并执行 luaL_dofile(lua, "test.lua"); // 解析lua文件
lua_getglobal(lua, "func"); // 获取func函数
lua_pushnumber(lua, 1); // 对第一个参数压栈
lua_pushnumber(lua, 2); // 对第二个参数压栈
if (lua_pcall(lua, 2, 1, 0) != 0) // 执行函数
{
printf("call lua failed!!!");
return 0;
} int nRes = (int)lua_tonumber(lua, -1); // 从栈顶取结果
printf("%d\n", nRes); ::lua_pop(lua, 1); // 将结果弹栈 lua_close (lua); // 关闭lua库
‘伍’ libtolua.a是自己编译的么
可以找被人编译的借鉴一下
‘陆’ unity slua 和 tolua slua哪个更好
更新LUa其实也是更新资源。 Lua被看作一个资源么。Lua代码都是运行时才编译的,不运行的时候就如同一张图片、一段音频一样,都是文件资源;所以更新逻辑只需要更新脚本,不需要再编译,因而Lua能轻松实现“热更新”。运行效率由于使用反射,所以成为它与生俱来的诟病。目前有对他的改进,像C#ToLua、Slua。但是Ulua是很成熟的,这个对于项目开发我认为暂时比性能重要!很多人在用,很多坑都已经被人采完。个人比较看好Slua的发展。当然了还有李总的L#走的就不是Lua的路。
网上还有说nLua的,我是新手不了解。 看看权威的解释:
ulua包含两种c模式(luajit版+原生luavm版),加之tolua c#提供了直接访问渠道。所以追求效率的,请选用ulua。但是ulua因为底层使用luajit,而luajit目前不能在WP使用,所以如果ulua支持WP需要第二种原生luavm的底层库。
nlua包含2种模式(KeraLua c版本)(KopiLuac#版本),它支持全,因为c版本底层用的原始的luavm(非luajit)。但是缺少tolua c#的支持,因此效率略低于ulua,但是支持WP(其他也支持)。
‘柒’ 如何给lua添加动态链接机制,以实现lua调用c++模块如何编译
定义如下宏为 1:
Mac: LUA_USE_MACOSX
Linux: LUA_USE_LINUX
Windows: LUA_USE_WIN
‘捌’ cocos2dx-lua中怎么使用自定义类以及tolua++的使用
使用cocos2dx-lua开发,免不了自己定义类,但是如何使用自定义的类的?
先了解下lua如何调用c++的:
lua脚本代码->通过coocs2dx中间解析层代码->将其转换并调用cocos2dx c++的前端代码
coocs2dx中间解析层代码都在libs/lua/cocos2dx_support/LuaCocos2d.cpp 这个文件中,想了解的可以自己去看下这个文件。
也就是说,你自己定义了一个类,lua能够调用你自己定义的类,你的自定义类就必须在LuaCocos2d.cpp这个中间解析文件中申明。
看了LuaCocos2d.cpp这个文件,可能有的同学都晕了,不知道怎么在LuaCocos2d.cpp中申明自己的定义的类。不过,不用担心,cocos2dx已经提供了tolua++这个工具自动编译生成新的LuaCocos2d.cpp文件。
下面开始进入正题。
一、创建一个coocs2dx-lua 的Demo工程,然后在class中自己定义个类。
SNSprite.h
[/cpp]
//
// SNSprite.h
// LuaDemo
//
// Created by LiuYanghui on 13-4-8.
//
//
#ifndef __LuaDemo__SNSprite__
#define __LuaDemo__SNSprite__
#include “cocos2d.h”
USING_NS_CC;
class SNSprite : public CCSprite{
public:
static SNSprite* create(const char* name);
private:
void initData();
};
#endif /* defined(__LuaDemo__SNSprite__) */
[/cpp]
SNSprite.cpp
C++
local function createSunnyLayer()
local layerSunny = CCLayer:create()
local labTips = CCLabelTTF:create("这个icon图标就是使用的自定义类", "Arial", 18)
labTips:setPosition(ccp(240,280))
layerSunny:addChild(labTips)
local sp = SNSprite:create("Icon.png")
sp:setPosition(ccp(100,100))
layerSunny:addChild(sp)
return layerSunny
end
-- play background music, preload effec t
添加到scene中:
C++
-- run
local sceneGame = CCScene:create() -- 创建场景
--sceneGame:addChild(createLayerFarm()) -- 将农场层加入场景
--sceneGame:addChild(createLayerMenu()) -- 将菜单界面层加入场景
sceneGame:addChild(createSunnyLayer())
CCDirector:sharedDirector():runWithScene(sceneGame)
OK,xcode编译运行,就看到效果了。