谁能给我讲讲三人行PKG

Guide&for&pkg-config
Dan&Nicholson
Translated&By&Bob
------------------------------------------------------
-----------------------------------------------
这个文档的目的是从用户和开发者的角度给一个pkg-config工具的使用概述。本文复习一些pkg-config背后的概念,怎样写pkg-config文件来支持你的项目,以及怎样用pkg-config集成第三方项目。
关于pkg-config的更多信息可以在和pkg-config的man手册中找到。
本文档假的pkg-config在类UNIX操作系统中使用,例如Linux。其他平台可能在一些细节上的存在差别。
现代计算机系统使用了很多分层组件为用户提供应用。其中一个困难就是如何正确的整合这些组件。pkg-config会收集系统中安装的库的数据,然后提供给用户。
如果没有pkg-config这样的数据系统,定位计算机提供的服务和获取它们的细节会很困难。对于开发者,安装软件包的pkg-config文件极大的简化了对API的获取。
使用pkg-config的初级阶段是为编译和链接程序时提供必要的细节。数据存储在pkg-config文件中。这些文件有一个.pc的后缀,放在一个特定的、pkg-config工具所知道的位置。我们会在后面描述更多的细节。
这个文件的格式包括预定义的关键字和自由形式的变量。例如:
prefix=/usr/local
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib
Description: The foo library
Version: 1.0.0
Cflags: -I${includedir}/foo
Libs: -L${libdir} -lfoo
以预定义关键字Name:为例,以关键字开头,后面跟一个冒号和一个值。变量是一个字符串和一个值,例如prefix=,用等号分开。关键字是由pkg-config定义和输出的。变量不是必须的,但可以被关键字用来定位和存储pkg-config没有覆盖的数据。
这里只是简单的描述一下关键字。更深入的描述和怎样有效的使用它们将在“写pkg-config文件”段中给出。
Name:一个人们可读的链接库或软件包的名称,这不影响pkg-config的使用,它用的是.pc文件的名称。
Description:关于软件包的简单描述。
URL:一个URL,可以在那里获得更多的信息,并且下载这个软件包。
Version:软件包的版本。
Requires:这个软件包所需的包的列表。这些包的版本可能用一写运算符来指定:=、&、&、&=、&=。
Requires.private:这个软件包所需的私有包的列表,不会暴露给应用。版本的指定规则与Requires相同。
Conflicts:可选,描述了会与这个软件包产生冲突的包。版本的指定规则与Requires相同。这个域会提供同一个包的多个实例,例如:Conflicts:&bar&&&1.2.3,&bar&&=&1.3.0。
Cflags:为这个软件包指定编译器选项,以及pkg-config不支持的必要的库。如果所需的库支持pkg-config,应该将它们添加到Requires和Requires.private。
Libs:为这个软件包指定的链接选项,以及pkg-config不支持的必要的库。与Cflags的规则相同。
Libs.private:这个软件包所需的私有库的链接选项,不会暴露给应用。规则与Cflags相同。
写pkg-config文件
为一个软件包创建pkg-config时,首先要确定怎样描述它。一个文件最好只用于描述一个库,所以,每个软件包至少需要像它所需的链接库那么多的pkg-config文件。
软件包的名字是由pkg-config数据文件的名字确定的。就是文件名去掉.pc后缀的那一部分。通常都用库的名字命名.pc文件。例如,一个安装libfoo.so的包会有一个相应的libfoo.c文件来包含pkg-config数据。这不是必须的,.pc文件仅仅是一个对你的库的唯一标识符。所以,foo.pc或foolib.pc也能正常工作。
Name、Description和URL的值是纯粹的信息,容易填写。Version比较棘手,它要确保这个包可以被用户使用。pkg-config使用RPM算法来进行版本比较。Version最好是用点分开的十进制数字,例如1.2.3,因为字母可能引起意外的结果。数字应该是单调递增的,并且要竟可能具体的描述这个库。通常使用包的版本号即可,这样可以方便使用者跟踪。
在描述更多的有用的关键字之前,有必要展示一下变量的定义。最常见的用法是定义安装路径,这样就不会使其他字段显得杂乱。因为变量是扩大递归的,在结合autoconf派生路径时,这会很有用。
prefix=/usr/local
includedir=${prefix}/include
Cflags: -I${includedir}/foo
最重要的pkg-config数据字段是Requires,Requires.private,Cflags,Libs&和&Libs.private。它们定义的数据被外部项目用来编译和链接库。
Requires和Requires.private定义了库所需的其他模块。通常首选Requires.private,以便避免程序链接到一些不必要的库。如果一个程序不使用所需库的符号,它就不应该直接链接到这个库。可以在的讨论中看到更多详细的解释。
由于pkg-config通常会公开Requires库的链接标识,这些模块会变成程序的直接依赖。另外,Requires.private中的库只有在静态链接是才会被包含。正因如此,pkg-config通常只会适当的从Requires中的同一个包中添加模块。
Libs包含了使用库是所必须的链接标识。此外,Libs和Libs.private还包含了pkg-config不支持的库的链接标识。与Requires类似,首选将外部库的链接标识添加到Libs.private,这样,程序就不会获得额外的直接依赖。
最后,Cflags包含了所用的库的编译标识。与Libs不同,Cflags没有私有变种。这是因为,数据类型和宏定义在任何链接情况下都是需要的。
使用pkg-config文件
假设系统中已经安装了.pc文件,pkg-config工具就被用来提取其中的数据。执行pkg-config&--help命令可以看到一些关于命令选项的简单描述。深入的描述可以在pkg-config(1)的man手册页中找到。本地将对一些常见的用法进行简单的描述。
假设系统中已经有了两个模块:foo和bar。它们的.pc文件可能像下面这样:
prefix=/usr
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib
Description: The foo library
Version: 1.0.0
Cflags: -I${includedir}/foo
Libs: -L${libdir} -lfoo
prefix=/usr
exec_prefix=${prefix}
includedir=${prefix}/include
libdir=${exec_prefix}/lib
Description: The bar library
Version: 2.1.2
Requires.private: foo &= 0.7
Cflags: -I${includedir}
Libs: -L${libdir} -lbar
模块的版本可以用--modversion选项获得。
$ pkg-config --modversion foo
$ pkg-config --modversion bar
要打印模块的链接标识,就用--libs选项。
$ pkg-config --libs foo
$ pkg-config --libs bar
请注意,pkg-config压缩了两个模块Libs字段。这是因为pkg-config对-L标识有特殊处理,它知道${libdir}目录/usr/lib是系统链接器搜素路径的一部分。也就是pkg-config受到了链接器选项的影响。
还有就是,虽然foo是bar所需要的,但是没有输出foo的链接标识。这是因为,只使用bar库的应用并不直接需要foo。对应静态链接bar的应用,我们需要两个链接标识:
$ pkg-config --libs --static bar
-lbar -lfoo
这种情况下,pkg-config就要输出两个链接标识,这样才能保证静态链接的应用可以找到所有必须的符号。另一方面,它会输出所有的Cflags字段。
$ pkg-config --cflags bar
-I/usr/include/foo
$ pkg-config --cflags --static bar
-I/usr/include/foo
还有一个有用的选项,--exists,可以用来测试模块的可用性。
$ pkg-config --exists foo
最值得注意的pkg-config特性是它所提供的版本检测,可以用来确定某个版本是否可用。
$ pkg-config --exists foo
有些命令在结合--print-errors选项使用时可以输出更详细的信息。
$ pkg-config --exists --print-errors xoxo
Package xoxo was not found in the pkg-config search path.
Perhaps you should add the directory containing `xoxo.pc'
to the PKG_CONFIG_PATH environment variable
No package 'xoxo' found
上面的信息出现了PKG_CONFIG_PATH环境变量。这个变量用来配置pkg-config的搜索路径。在类Unix操作系统中,会搜索/usr/lib/pkconfig和/usr/share/pkgconfig目录。这通常已经覆盖了系统已经安装的模块。但是,有些本地模块可能安装在了其他路径,例如/usr/local。这种情况下,需要指定搜索路径,以便pkg-config可以定位.pc文件。
$ pkg-config --modversion hello
Package hello was not found in the pkg-config search path.
Perhaps you should add the directory containing `hello.pc'
to the PKG_CONFIG_PATH environment variable
No package 'hello' found
$ export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
$ pkg-config --modversion hello
也提供了一些宏,可以将pkg-config集成到项目中。
*&PKG_PROG_PKG_CONFIG([MIN-VERSION]):定位系统中的pkg-config工具,并检测版本兼容性。
* PKG_CHECK_EXISTS(MODULES,[ACTION-IF-FOUND],&[ACTION-IF-NOT-FOUND]):检测指定的模块是否存在。
* PKG_CHECK_MODULES(VARIABLE-PREFIX,MODULES,&[ACTION-IF-FOUND],&[ACTION-IF-NOT-FOUND])::检测指定的模块是否存在,如果存在,就根据&pkg-config&--cflags和pkg-config&--libs的输出设置&VARIABLE-PREFIX&_CFLAGS&and&&VARIABLE-PREFIX&_LIBS。
1.&我的程序使用了x库,我该怎么做?
pkg-config的输出可以在编译命令中使用,假设x库已经有了一个叫做x.pc的pkg-config文件:
cc `pkg-config --cflags --libs x` -o myapp myapp.c
将pkg-config集成到和中使用会更强大。但是,用PKG_CONFIG_PATH宏可以很容易的在建立过程中访问元数据。
configure.ac:
PKG_CHECK_MODULES([X], [x])
Makefile.am:
myapp_CFLAGS = $(X_CFLAGS)
myapp_LDADD = $(X_LIBS)
如果找到了x模块,宏会填充和替代X_CFLAGS和X_LIBS变量。如果没有找到,会产生错误。配置PKG_CHECK_MODULES的第3、4个参数,可以控制没有找到模块时的动作。
2.&我的z库安装了保护libx头的头文件。我应该在z.pc中添加什么?
如果x库支持pkg-config,将它添加到Requires.private字段。如果不支持,就配置Cflags字段,添加一些使用libx头时所需的编译器标识。在这两种情况下,无论是否使用了--static,pkg-config都会输出编译器标识。
3.&我的z库内部使用了libx,但是不能再公开API中暴露libx的数据类型。我应该在z.pc中添加什么?
同样的,如果x支持pkg-config,就把它添加到Requires.private。这种情况下,就没必要发出编译器标识,但是在今天链接时要确保有链接器标识。如果libx不支持pkg-config,就将必要的链接器标识添加到Libs.private。
——————————————————————
Dan&Nicholson&&dbn.lists&(at)&gmail&(dot)&com&
Copyright&(C)&2010&Dan&Nicholson.
This&document&is&licensed&under&the&&or&any&later&version.
本文已收录于以下专栏:
相关文章推荐
pkg-config的种种知识,你要的都在这!!!
你在 Unix 或 Linux 下开发过软件吗?写完一个程序,编译运行完全正常,在你本机上工作得好好的,你放到源代码管理系统中。然后,告诉你的同事说,你可以取下来用了。这时,你长长的出了一口气,几天的...
通常来说gcc在编译链接linux环境下的c语言代码时会在/lib和/usr/lib中去寻找对应的库文件,如果库文件没有这两个位置的时候则需要将库文件信息添加到库文件搜索路径中,可以通过如下两种方法来...
他的最新文章
讲师:汪剑
讲师:刘道宽
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)帖子很冷清,卤煮很失落!求安慰
手机签到经验翻倍!快来扫一扫!
大V请给我讲讲怎么用?
10浏览 / 11回复
天际通与亲情关怀是干什么用的?
提供的小技巧试试
楼主你好,亲情关怀是会员服务提供的远程协助服务,只需很简单的操作就可以远程求助他人、或者远程帮助他人解决手机问题。天际通是华为推出的面向特定机型的上网应用,可以为用户提供“国内WLAN”、“全球WLAN”和“全球移动数据”三种上网服务(不同机型支持部分或全部服务)。使用“国内WLAN”可以免费连接ChinaNet热点,使用“全球WLAN”可以免费连接分布在海外100多个国家/地区的约5700万公共场所的热点,使用“全球移动数据”可以免SIM卡海外数据上网,套餐即买即用。
简单点说就是类似qq远程,可以远程操控别人手机
搔捏木我搔 发表于
楼主你好,亲情关怀是会员服务提供的远程协助服务,只需很简单的操作就可以远程求助他人、或者远程帮助他人 ...
你简单点说呀,,没看明白呀,是不是用这个可以免费上网?如果是请用是谁的网
提供的小技巧试试!
天际通是无线接入当地Wi-Fi热点的业务程序,每天登录可以获得免费Wi-Fi时长,国外的话用处更多一些。
亲情关怀是另一个操作指导者远程控制本机进行某些操作的应用。主要用来远程协助本机进行操作设置排除故障等。
负分拿好,不送,滚粗
闪瞎了我的钛合金狗眼
就是这么快。
额~(此回复只有一个字,却代表了我对此贴极其的无奈,结合语境和那完美的一个“~”,完整的揭示了我的无比的无语的思想感情,给楼上以升华,给楼下以启发……)
您需要登录后才可以回帖&&&|&&&&&
可能感兴趣的板块:
用户名/注册邮箱/注册手机号
其他第三方号登录『 不要让任何事情成为你不去学习的理由!』
【COCOS2DX-LUA 脚本开发之四】使用tolua++编译pkg,从而创建自定义类让Lua脚本使用
本站文章均为
原创,转载务必在明显处注明:
转载自【黑米GameDev街区】 原文链接:
在Lua第三篇中介绍了,如何在cocos2dx中使用Lua创建自定义类供Lua脚本调用使用,当时出于Himi对Lua研究不够深入,所以当时使用了笨方法手动添加的方式进行的,那么本篇将介绍利用tolua++快速将我们自定义的c2dx类嵌入,供 lua脚本使用。
首先介绍整个过程:
之前我们的过程: 自定义类-&手动到LuaCoco2d.cpp中手动添加binding-&lua使用
现在我们的过程是: 自定义类-&使用tolua++工具编译到LuaCoco2d.cpp中-&lua使用
下面进行详细步骤讲解:
步骤一:首先自定义类(这里Himi自定义类名 “MySprite”)
MySprite.h
MySprite.h
Created by Himi on 13-4-7.
#ifndef __mtet__MySprite__
#define __mtet__MySprite__
#include "cocos2d.h"
using namespace cocos2d;
class MySprite : public CCSprite{
static MySprite* createMS(const char* fileName);
#endif /* defined(__mtet__MySprite__) */
12345678910111213141516171819
////&&MySprite.h//&&mtet////&&Created by Himi on 13-4-7.////&#ifndef __mtet__MySprite__#define __mtet__MySprite__&#include "cocos2d.h"using namespace cocos2d;&class MySprite : public CCSprite{public:&&&&static MySprite* createMS(const char* fileName);};#endif /* defined(__mtet__MySprite__) */
MySprite.cpp
MySprite.cpp
Created by Himi on 13-4-7.
#include "MySprite.h"
MySprite* MySprite::createMS(const char* fileName){
MySprite* sp = new MySprite();
if(sp && sp-&initWithFile(fileName)){
sp-&setPosition(ccp(100,100));
sp-&autorelease();
CC_SAFE_DELETE(sp);
return NULL;
12345678910111213141516171819
////&&MySprite.cpp//&&mtet////&&Created by Himi on 13-4-7.////&#include "MySprite.h"MySprite* MySprite::createMS(const char* fileName){&&&&MySprite* sp = new MySprite();&&&&if(sp && sp->initWithFile(fileName)){&&&&&&&&sp->setPosition(ccp(100,100));&&&&&&&&sp->autorelease();&&&&&&&&return sp;&&&&}&&&&CC_SAFE_DELETE(sp);&&&&return NULL;}
步骤二:利用tolua++编译我们创建的pkg,将自定义类嵌入LuaCocos2d.cpp中
首先我们到cocos2dx引擎目录下找到tools下的tolua++文件夹。
然后你看到很多的pkg文件,你可以使用文本打开,就会发现都是Cocos2dx引擎封装的类、函数定义,如下CCSprite.pkg
typedef enum {
//! Translate with it's parent
CC_HONOR_PARENT_TRANSFORM_TRANSLATE =
//! Rotate with it's parent
CC_HONOR_PARENT_TRANSFORM_ROTATE =
//! Scale with it's parent
CC_HONOR_PARENT_TRANSFORM_SCALE
//! Skew with it's parent
CC_HONOR_PARENT_TRANSFORM_SKEW
//! All possible transformation enabled. Default value.
CC_HONOR_PARENT_TRANSFORM_ALL
CC_HONOR_PARENT_TRANSFORM_TRANSLATE | CC_HONOR_PARENT_TRANSFORM_ROTATE | CC_HONOR_PARENT_TRANSFORM_SCALE | CC_HONOR_PARENT_TRANSFORM_SKEW,
} ccHonorParentT
class CCSprite : public CCNode
void setDirty(bool bDirty);
bool isDirty(void);
ccV3F_C4B_T2F_Quad getQuad(void);
CCRect getTextureRect(void);
//bool isUsesBatchNode(void);
bool isTextureRectRotated(void);
void setAtlasIndex(unsigned int uAtlasIndex);
unsigned int getAtlasIndex(void);
//void setUsesSpriteBatchNode(bool bUsesSpriteBatchNode);
void setTextureAtlas(CCTextureAtlas *pobTextureAtlas);
CCTextureAtlas* getTextureAtlas(void);
//void setSpriteBatchNode(CCSpriteBatchNode *pobSpriteBatchNode);
//CCSpriteBatchNode* getSpriteBatchNode(void);
//void setHonorParentTransform(ccHonorParentTransform eHonorParentTransform);
//ccHonorParentTransform getHonorParentTransform(void);
void setBlendFunc(ccBlendFunc blendFunc);
ccBlendFunc getBlendFunc(void);
CCPoint getOffsetPosition(void);
void ignoreAnchorPointForPosition(bool newValue);
void setFlipX(bool bFlipX);
void setFlipY(bool bFlipY);
bool isFlipX(void);
bool isFlipY(void);
void removeChild(CCNode* pChild, bool bCleanUp);
void removeAllChildrenWithCleanup(bool bCleanup);
void reorderChild(CCNode* pChild, int zOrder);
void addChild(CCNode* pChild);
void addChild(CCNode* pChild, int zOrder);
void addChild(CCNode* pChild, int zOrder, int tag);
void sortAllChildren();
//void setPosition(CCPoint pos);
void setRotation(float rotation);
void setSkewX(float sx);
void setSkewY(float sy);
void setScale(float fScale);
void setScaleX(float fScaleX);
void setScaleY(float fScaleY);
void setVertexZ(float fVertexZ);
void setAnchorPoint(const CCPoint & anchor);
void setVisible(bool bVisible);
void setOpacity(GLubyte opacity);
GLubyte getOpacity(void);
void setColor(ccColor3B color3);
ccColor3B getColor(void);
void setOpacityModifyRGB(bool bValue);
bool isOpacityModifyRGB(void);
void setTexture(CCTexture2D *texture);
CCTexture2D* getTexture(void);
void updateTransform(void);
//void useSelfRender(void);
void setTextureRect(CCRect rect);
void setTextureRect(CCRect rect, bool rotated, CCSize size);
void setVertexRect(CCRect rect);
//void useBatchNode(CCSpriteBatchNode *batchNode);
void setDisplayFrame(CCSpriteFrame *pNewFrame);
bool isFrameDisplayed(CCSpriteFrame *pFrame);
CCSpriteFrame* displayFrame(void);
void setBatchNode(CCSpriteBatchNode* pBatchNode);
CCSpriteBatchNode* getBatchNode();
void setDisplayFrameWithAnimationName(const char *animationName, int frameIndex);
static CCSprite* createWithTexture(CCTexture2D *pTexture);
static CCSprite* createWithTexture(CCTexture2D *pTexture, CCRect rect);
static CCSprite* createWithSpriteFrame(CCSpriteFrame *pSpriteFrame);
static CCSprite* createWithSpriteFrameName(const char *pszSpriteFrameName);
static CCSprite* create(const char *pszFileName, CCRect rect);
static CCSprite* create(const char *pszFileName);
static CCSprite* create();
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
/*typedef enum { //! Translate with it's parent CC_HONOR_PARENT_TRANSFORM_TRANSLATE =&&1 && 0, //! Rotate with it's parent CC_HONOR_PARENT_TRANSFORM_ROTATE =&&1 && 1, //! Scale with it's parent CC_HONOR_PARENT_TRANSFORM_SCALE
=&&1 && 2, //! Skew with it's parent CC_HONOR_PARENT_TRANSFORM_SKEW
=&&1 && 3,& //! All possible transformation enabled. Default value. CC_HONOR_PARENT_TRANSFORM_ALL
=&&CC_HONOR_PARENT_TRANSFORM_TRANSLATE | CC_HONOR_PARENT_TRANSFORM_ROTATE | CC_HONOR_PARENT_TRANSFORM_SCALE | CC_HONOR_PARENT_TRANSFORM_SKEW,&} ccHonorParentT*/class CCSprite : public CCNode{ void setDirty(bool bDirty); bool isDirty(void);& ccV3F_C4B_T2F_Quad getQuad(void);& CCRect getTextureRect(void); //bool isUsesBatchNode(void); bool isTextureRectRotated(void);& void setAtlasIndex(unsigned int uAtlasIndex); unsigned int getAtlasIndex(void); //void setUsesSpriteBatchNode(bool bUsesSpriteBatchNode); void setTextureAtlas(CCTextureAtlas *pobTextureAtlas); CCTextureAtlas* getTextureAtlas(void); //void setSpriteBatchNode(CCSpriteBatchNode *pobSpriteBatchNode); //CCSpriteBatchNode* getSpriteBatchNode(void); //void setHonorParentTransform(ccHonorParentTransform eHonorParentTransform); //ccHonorParentTransform getHonorParentTransform(void); void setBlendFunc(ccBlendFunc blendFunc); ccBlendFunc getBlendFunc(void);& CCPoint getOffsetPosition(void);& void ignoreAnchorPointForPosition(bool newValue); void setFlipX(bool bFlipX); void setFlipY(bool bFlipY); bool isFlipX(void); bool isFlipY(void);& void removeChild(CCNode* pChild, bool bCleanUp); void removeAllChildrenWithCleanup(bool bCleanup); void reorderChild(CCNode* pChild, int zOrder); void addChild(CCNode* pChild); void addChild(CCNode* pChild, int zOrder); void addChild(CCNode* pChild, int zOrder, int tag); void sortAllChildren(); //void setPosition(CCPoint pos); void setRotation(float rotation); void setSkewX(float sx); void setSkewY(float sy); void setScale(float fScale); void setScaleX(float fScaleX); void setScaleY(float fScaleY); void setVertexZ(float fVertexZ); void setAnchorPoint(const CCPoint & anchor); void setVisible(bool bVisible);& void setOpacity(GLubyte opacity); GLubyte getOpacity(void);& void setColor(ccColor3B color3); ccColor3B getColor(void); void setOpacityModifyRGB(bool bValue); bool isOpacityModifyRGB(void);& void setTexture(CCTexture2D *texture); CCTexture2D* getTexture(void);& void updateTransform(void); //void useSelfRender(void); void setTextureRect(CCRect rect); void setTextureRect(CCRect rect, bool rotated, CCSize size); void setVertexRect(CCRect rect); //void useBatchNode(CCSpriteBatchNode *batchNode); void setDisplayFrame(CCSpriteFrame *pNewFrame); bool isFrameDisplayed(CCSpriteFrame *pFrame); CCSpriteFrame* displayFrame(void); void setBatchNode(CCSpriteBatchNode* pBatchNode); CCSpriteBatchNode* getBatchNode(); void setDisplayFrameWithAnimationName(const char *animationName, int frameIndex);& static CCSprite* createWithTexture(CCTexture2D *pTexture); static CCSprite* createWithTexture(CCTexture2D *pTexture, CCRect rect); static CCSprite* createWithSpriteFrame(CCSpriteFrame *pSpriteFrame); static CCSprite* createWithSpriteFrameName(const char *pszSpriteFrameName); static CCSprite* create(const char *pszFileName, CCRect rect); static CCSprite* create(const char *pszFileName); static CCSprite* create();};
没错,我们也会按照类似方式进行创建我们自定义类的pkg文件。
我们自定义一个文件(文本、xcode等都可以),后缀 .pkg ,然后将Himi自定义的MySprite类定义到pkg中,如下:
注意:只要自定义类.h中的内容,至于cpp的实现,binding后lua自动调用你类的函数
MySprite.pkg
class MySprite : public CCSprite{
static MySprite* createMS(const char* fileName);
class MySprite : public CCSprite{ static MySprite* createMS(const char* fileName);};
在pkg中我只是定义了创建函数而已,至于更多的函数就交给大家自定义啦,另外我们注意书写pkg时是需要几条规则的,其实在tolua++这个文件夹中我们也能看到有一个名字叫 README 的文件,打开如下:
1. Generating the lua&--&C bindings with tolua++
Build scripts for windows (build.bat) and unix (build.sh) are provided
to generate the relevant files after modifying the .pkg files.
scripts basically run the following command:
tolua++.exe -L basic.lua -o LuaCocos2d.cpp Cocos2d.pkg
This will generate the bindings file and patch it with come cocos2dx
specific modifications.
On POSIX systems you can also just run "make" to build the bindings
if/when you change .pkg files.
2. Writing .pkg files
1) enum keeps the same
2) remove CC_DLL for the class defines, pay attention to multi inherites
3) remove inline keyword for declaration and implementation
4) remove public protect and private
5) remove the decalration of class member variable
6) keep static keyword
7) remove memeber functions that declared as private or protected
1234567891011121314151617181920212223
1. Generating the lua<-->C bindings with tolua++&&&&&Build scripts for windows (build.bat) and unix (build.sh) are provided&&&&to generate the relevant files after modifying the .pkg files.&&These&&&&scripts basically run the following command:&&&&&&&&&tolua++.exe -L basic.lua -o LuaCocos2d.cpp Cocos2d.pkg&&&&&This will generate the bindings file and patch it with come cocos2dx&&&&specific modifications.&&&&&On POSIX systems you can also just run "make" to build the bindings&&&&if/when you change .pkg files.&2. Writing .pkg files&&&&&1) enum keeps the same&&&&2) remove CC_DLL for the class defines, pay attention to multi inherites&&&&3) remove inline keyword for declaration and implementation&&&&4) remove public protect and private&&&&5) remove the decalration of class member variable&&&&6) keep static keyword&&&&7) remove memeber functions that declared as private or protected
这个文件声明了书写pkg的规则,不多赘述。
书写好我们的pkg之后,将pkg文件放置此tolua++文件夹下即可,然后配置我们tolua++工具。
继续在tolua++文件夹中解压tolua++.Mac.zip 文件,会得到一个tolua++的工具,如下图:
解压出工具之后,我们还要在tolua++文件夹中,配置tolua++路径,打开“build.sh”文件,如下:
这里 TOLUA 是tolua++工具的位置(路径后面要架上 /tolua++
表示这个工具),最下面配置的是编译后的luaCocos2d.cpp文件导出的位置,Himi这里配置到桌面,配置如下:
最后,我们要将我们定义的pkg文件注册到 tolua++文件夹下的Cocos2d.pkg中,如下:
如上步骤都OK后,我们就可以使用“终端”,先cd到tolua++的文件夹下,然后使用“make”命令执行tolua++工具。
(如果这里终端不能正常执行, 请继续修改tolua++文件夹下的: makefile
,将其路径配置一下即可。)
终端正常执行后,会在一开始指定的目录生成LuaCocos2d.cpp 文件,且其中已经binding好了自定义类,将生成的LuaCocos2d.cpp替换到你项目的/libs/lua/cocos2dx_support下的LuaCocos2d.cpp 文件。
Himi建议生成的LuaCocos2d.cpp 文件路径直接设置你的项目的/libs/lua/cocos2dx_support下很方便
注意:这时候LuaCoco2d.cpp中虽然已经binding了我们的自定义类,但是没有引用我们的头文件,所以我们还需要在LuaCocos2d.h中倒入我们自定义类.h 。
步骤三:Lua测试我们的自定义类
-- for CCLuaEngine traceback
function __G__TRACKBACK__(msg)
print("----------------------------------------")
print("LUA ERROR: " .. tostring(msg) .. "\n")
print(debug.traceback())
print("----------------------------------------")
local function main()
-- avoid memory leak
collectgarbage("setpause", 100)
collectgarbage("setstepmul", 5000)
local cclog = function(...)
print(string.format(...))
require "hello2"
cclog("result is " .. myadd(3, 5))
---------------
-- create farm
local function createLayerFarm()
local layerFarm = CCLayer:create()
local font = CCLabelTTF:create("Himi 使用tolua++ binding自定义类", "Verdana-BoldItalic", 20)
font:setPosition(ccp(220,260))
layerFarm:addChild(font)
= MySprite:createMS("Icon.png")
layerFarm:addChild(ms)
return layerFarm
local sceneGame = CCScene:create()
sceneGame:addChild(createLayerFarm())
CCDirector:sharedDirector():runWithScene(sceneGame)
xpcall(main, __G__TRACKBACK__)
12345678910111213141516171819202122232425262728293031323334353637383940414243
-- for CCLuaEngine tracebackfunction __G__TRACKBACK__(msg)&&&&print("----------------------------------------")&&&&print("LUA ERROR: " .. tostring(msg) .. "\n")&&&&print(debug.traceback())&&&&print("----------------------------------------")end&local function main()&&&&-- avoid memory leak&&&&collectgarbage("setpause", 100)&&&&collectgarbage("setstepmul", 5000)&&&&&local cclog = function(...)&&&&&&&&print(string.format(...))&&&&end&&&&&require "hello2"&&&&cclog("result is " .. myadd(3, 5))&&&&&---------------&&&&&-- create farm&&&&local function createLayerFarm()&&&&&&&&local layerFarm = CCLayer:create()&&&&&&&&&local font = CCLabelTTF:create("Himi 使用tolua++ binding自定义类", "Verdana-BoldItalic", 20)&&&&&&&&font:setPosition(ccp(220,260))&&&&&&&&layerFarm:addChild(font)&&&&&&&&&local ms&&= MySprite:createMS("Icon.png")&&&&&&&&layerFarm:addChild(ms)&&&&&&&&&return layerFarm&&&&end&&&&&-- run&&&&local sceneGame = CCScene:create()&&&&sceneGame:addChild(createLayerFarm())&&&&CCDirector:sharedDirector():runWithScene(sceneGame)end&xpcall(main, __G__TRACKBACK__)
运行截图如下:
OK,今天就到这,希望大家多多探讨,有问题请及时留言。
广播: dser
? 【Unreal Engine 】 ? 【React Native】 ? 【Cocos Creator】? 【Cocos2dx】? 【C2dx-Lua】
Himi’s Book
小广告先森
小广告先森}

我要回帖

更多关于 我的二战不可能这么萌 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信