当前位置: 首页 > news >正文

兴安盟做网站公司wordpress七牛云加速

兴安盟做网站公司,wordpress七牛云加速,网站建设 保障接单 计划,网站建设app开发学习最近为了总结Lua绑定C/C对象的各种方法、第三方库和原理#xff0c;学习了LuaBridge库为Lua绑定C/C对象#xff0c;下面是学习笔记#xff0c;实质是对该库的 Reference Manual 基本上翻译了一遍#xff0c;学习过程中测试代码#xff0c;放在 我的github 上。 LuaBridge的… 最近为了总结Lua绑定C/C对象的各种方法、第三方库和原理学习了LuaBridge库为Lua绑定C/C对象下面是学习笔记实质是对该库的 Reference Manual 基本上翻译了一遍学习过程中测试代码放在 我的github 上。 LuaBridge的主要特点       源码只有头文件没有.cpp文件没有MakeFile使用时只需一个#include即可。       支持不同的对象生命周期管理模式。       对Lua栈访问方便并且是类型安全的type-safe。       Automatic function parameter type binding.       Easy access to Lua objects like tables and functions.       LuaBridge的API是基于C模板元编程template metaprogramming的。在编译时这些模板自动生成各种Lua API调用从而可以再Lua脚本中使用C程序中的类和函数。 为了能在C中使用Lua的数据比如number,string,table以及方便调用Lua的函数使用LuaBridge中的LuaRef类可以方便做到。  LuaBridge设计原则       由于LuaBridge的设计目标尽可能方便使用比如只有头文件、没有用到高级C的语法、不需要配置。因此LuaBridge性能虽足够好但并不是最好的比如 OOLuahttps://code.google.com/p/oolua/执行效率就比它好并且它也不像LuaBindhttp://www.rasterbar.com/products/luabind.html那样功能全面。 LuaBridge不支持下面特性       枚举型常量       不支持8个以上的函数或方法的调用       重载函数、方法和构造函数Overloaded functions, methods, or constructors       全局变量变量必须被包装在命名空间里       自动地转换STL容器类型和Table       在Lua中继承C类Inheriting Lua classes from C classes。       Passing nil to a C function that expects a pointer or reference       Standard containers like std::shared_ptr  在Lua访问C       为了在Lua中使用C中的数据和函数LuaBridge要求任何需要使用的数据的都需要注册。LuaBridge可以注册下面五种类型数据       Namespaces  一个Lua table包含了其他注册信息       Data  全局变量或静态变量、数据成员或静态数据成员       Functions  一般函数、成员函数或静态成员函数       CFunctions  A regular function, member function, or static member function that uses the lua_CFunction calling convention       Properties  Global properties, property members, and static property members. These appear like data to Lua,       but are implemented in C using functions to get and set the values. Data和Properties在注册时被标记为只读read-only。这不同于const这些对象的值能在C中修改但不能在Lua脚本中修改。 Namespaces       LuaBridge索引的注册都是在一个namespace中namespace是从lua角度来看的它实质上就是table注意这里的namespace不是C中的namespaceC的namespace 不是一定需要的。LuaBridge的namespace是对Lua脚本来说的它们被作为逻辑组合工具logical grouping tool。为了访问Lua的全局命名空间global namespace可以在C 中这样调用  getGlobalNamespace (L); 上面的调用会返回一个对象实质是table可用来进一步注册比如  getGlobalNamespace (L).beginNamespace (test); 上面的调用就会在Lua的_G中创建一个名为test的table现在这个table还是空的。LuaBridge保留所有以双下划线开头命名的标识因此__test是无效的命名 尽管这样命名LuaBridge不会报错。我们可以进一步扩展上面的注册  getGlobalNamespace (L).beginNamespace (test).beginNamespace (detail).endNamespace ().beginNamespace (utility).endNamespace ().endNamespace (); 这样注册后我们就可以在Lua中使用test, test.detail,和test.utility。这里的引入的endNamespace函数也会返回一个对象实质也是table该对象实质就是上一层namespace 表示当前namespace注册完成。 All LuaBridge functions which create registrations return an object upon which subsequent registrations can be made, allowing for an unlimited number of registrations to be chained together using the dot operator。在一个namespace中注册相同命名的对象对于LuaBridge来说是没有 定义的行为。一个namespace可以多次使用增加更多的成员。比如下面两段代码是等价的  getGlobalNamespace (L).beginNamespace (test).addFunction (foo, foo).endNamespace ();getGlobalNamespace (L).beginNamespace (test).addFunction (bar, bar).endNamespace (); 和  getGlobalNamespace (L).beginNamespace (test).addFunction (foo, foo).addFunction (bar, bar).endNamespace (); Data, Properties, Functions, and CFunctions       Data, Properties, Functions, and CFunctions可以依次使用addVariable,, addProperty, addFunction, and addCFunction来注册。在Lua脚本中调用注册的函数时 LuaBridge会自动地传入相应的参数并对参数类型转和检查。同样函数的返回值也会自动处理。当前LuaBridge最多可处理8个参数。Pointers, references, and objects of class type as parameters are treated specially。如果我们在C中有以下定义  int globalVar;static float staticVar;std::string stringProperty;std::string getString () { return stringProperty; }void setString (std::string s) { stringProperty s; }int foo () { return 42; }void bar (char const*) { }int cFunc (lua_State* L) { return 0; } 为了在Lua使用这些变量和函数我们可以按以下方式注册它们  getGlobalNamespace (L).beginNamespace (test).addVariable (var1, globalVar).addVariable (var2, staticVar, false) // read-only.addProperty (prop1, getString, setString).addProperty (prop2, getString) // read only.addFunction (foo, foo).addFunction (bar, bar).addCFunction (cfunc, cFunc).endNamespace ();Variables在注册时可以通过传递第二个参数为false确保Variables不会在Lua被修改默认第二个参数是true。Properties在注册时若不传递set函数则在脚本中是read-only。  通过上面注册后则下面表达式在Lua是有效的  test -- a namespace实质就是一个table下面都是table中的成员test.var1 -- a lua_Number variabletest.var2 -- a read-only lua_Number variabletest.prop1 -- a lua_String propertytest.prop2 -- a read-only lua_String propertytest.foo -- a function returning a lua_Numbertest.bar -- a function taking a lua_String as a parametertest.cfunc -- a function with a variable argument list and multi-return 注意test.prop1和test.prop2引用的C中同一个变量然后test.prop2是read-only因此在脚本中对test.prop2赋值会导致运行时错误run-time error。在Lua按以下方式使用  test.var1 5 -- okaytest.var2 6 -- error: var2 is not writabletest.prop1 Hello -- okaytest.prop1 68 -- okay, Lua converts the number to a string.test.prop2 bar -- error: prop2 is not writabletest.foo () -- calls foo and discards the return valuetest.var1 foo () -- calls foo and stores the result in var1test.bar (Employee) -- calls bar with a stringtest.bar (test) -- error: bar expects a string not a table Class Objects  类的注册是以beginClass或deriveClass开始以endClass结束。一个类注册完后还可以使用beginClass重新注册更多的信息但是deriveClass只能被使用一次。为了给已经用deriveClass注册的类注册更多的信息可以使用beginClass。  class A { public:A() { printf(A constructor\n);}static int staticData;static int getStaticData() {return staticData;}static float staticProperty;static float getStaticProperty () { return staticProperty; }static void setStaticProperty (float f) { staticProperty f; }static int staticCFunc (lua_State *L) { return 0; }std::string dataMember;char dataProperty;char getProperty () const { return dataProperty; }void setProperty (char v) { dataProperty v; }void func1 () {printf(func1 In Class A\n); }virtual void virtualFunc () {printf(virtualFunc In Class A\n); }int cfunc (lua_State* L) { printf(cfunc In Class A\n); return 0; }};class B : public A {public:B() { printf(B constructor\n);}double dataMember2;void func1 () {printf(func1 In Class B\n); }void func2 () { printf(func2 In Class B\n); }void virtualFunc () {printf(virtualFunc In Class B\n); }};int A::staticData 3;float A::staticProperty 0.5; 按下面方式注册  getGlobalNamespace (L).beginNamespace (test).beginClassA(A).addConstructor void (*) (void) ().addStaticData (staticData, A::staticData).addStaticProperty (staticProperty, A::getStaticData).addStaticFunction (getStaticProperty, A::getStaticProperty) //read-only.addStaticCFunction (staticCFunc, A::staticCFunc).addData (data, A::dataMember).addProperty (prop, A::getProperty, A::setProperty).addFunction (func1, A::func1).addFunction (virtualFunc, A::virtualFunc).addCFunction (cfunc, A::cfunc).endClass ().deriveClassB, A(B).addConstructor void (*) (void) ().addData (data, B::dataMember2).addFunction (func1, B::func1).addFunction (func2, B::func2).endClass ().endNamespace (); 注册后可以再Lua脚本中按一下方式使用  local AClassObj test.A () --create class A instanceprint(before:,test.A.staticData) -- access class A static member test.A.staticData 8 -- modify class A static member print(after:,test.A.staticData) print(before:, test.A.getStaticProperty()) --test.A.staticProperty 1.2 --error:can not modify print(staticCFunc)test.A.staticCFunc()AClassObj.data stingprint(dataMember:,AClassObj.data)AClassObj.prop aprint(property:,AClassObj.prop)AClassObj:func1()AClassObj:virtualFunc()AClassObj:cfunc()BClassObj test.B()BClassObj:func1()BClassObj:func2() BClassObj:virtualFunc()         其输出结果为  A constructorbefore: 3after: 8before: 0.5staticCFuncdataMember: stingproperty: afunc1 In Class AvirtualFunc In Class Acfunc In Class AA constructorB constructorfunc1 In Class Bfunc2 In Class BvirtualFunc In Class B 类的方法注册类似于通常的函数注册虚函数也是类似的没有特殊的语法。在LuaBridge中能识别const方法并且在调用时有检测的因此如果一个函数返回一个const object或包含指向const object的数据给Lua脚本则在Lua中这个被引用的对象则被认为是const的它只能调用const的方法。对于每个类析构函数自动注册的。无须在继承类中重新注册已在基类中注册过的方法。If a class has a base class that is **not** registeredwith Lua, there is no need to declare it as a subclass.  Constructors  为了在Lua中创建类的对象必须用addConstructor为改类注册构造函数。并且LuaBridge不能自动检测构造函数的参数个数和类型这与注册函数或方法能自动检测是不同的因此在用注册addConstructor时必须告诉LuaBridge在Lua脚本将用到的构造函数签名例如  struct A {A ();};struct B {explicit B (char const* s, int nChars);};getGlobalNamespace (L).beginNamespace (test).beginClass A (A).addConstructor void (*) (void) ().endClass ().beginClass B (B).addConstructor void (*) (char const*, int) ().endClass ();.endNamespace () 在Lua中就可以一些方式创建A和B的实例:  a test.A () -- Create a new A.b test.B (hello, 5) -- Create a new B.b test.B () -- Error: expected string in argument 1 lua_State*  有时候绑定的函数或成员函数需要lua_State*作为参数来访问栈。使用LuaBridge只需要在将要绑定的函数最后添加lua_State*类型的参数即可。比如  void useStateAndArgs (int i, std::string s, lua_State* L); getGlobalNamespace (L).addFunction (useStateAndArgs, useStateAndArgs); 在Lua中就可按以下方式使用  useStateAndArgs(42,hello) 在脚本中只需传递前面两个参数即可。注意 lua_State*类型的参数就放在定义的函数最后否则结果是未定义的。  Class Object Types  一个注册的类型T可能以下方式传递给Lua脚本  T* or T: Passed by reference, with _C lifetime_.T const* or T const: Passed by const reference, with _C lifetime_.T or T const: Passed by value (a copy), with _Lua lifetime_. C Lifetime  对于C lifetime的对象其创建和删除都由C代码控制Lua GC不能回收这些对象。当Lua通过lua_State*来引用对象时必须确保该对象还没删除否则将导致未定义的行为。例如可按以下方法给Lua传递  C lifetime的对象  A a;push (L, a); // pointer to a, C lifetimelua_setglobal (L, a);push (L, (A const*)a); // pointer to a const, C lifetimelua_setglobal (L, ac);push A const* (L, a); // equivalent to push (L, (A const*)a)lua_setglobal (L, ac2);push (L, new A); // compiles, but will leak memorylua_setglobal (L, ap); Lua Lifetime当C通过值传递给Lua一个对象时则该对象是Lua lifetime。在值传递时该对象将在Lua中以userdata形式保存并且当Lua不再引用该对象时该对象可以被GC回收。当userdata被回收时其相应对象的  析构函数也会被调用。在C中应用lua lifetime的对象时必须确保该对象还没被GC回收否则其行为是未定义的。例如可按以下方法给Lua传递的是Lua lifetime的催下  B b;push (L, b); // Copy of b passed, Lua lifetime.lua_setglobal (L, b); 当在Lua中调用注册的构造函数创建一个对象时该对象同样是Lua lifetime的当该对象不在被引用时GC会自动回收该对象。当然你可以把这个对象引用作为参数传递给C但需要保证C在通过引用使用该对象时  改对还没有被GC回收。   Pointers, References, and Pass by Value  当C对象作为参数从Lua中传回到C代码中时LuaBridge会尽可能做自动转换。比如向Lua中注册了以下C函数  void func0 (A a); void func1 (A* a); void func2 (A const* a); void func3 (A a); void func4 (A const a); 则在Lua中就可以按以下方式调用上面的函数  func0 (a) -- Passes a copy of a, using As copy constructor. func1 (a) -- Passes a pointer to a. func2 (a) -- Passes a pointer to a const a. func3 (a) -- Passes a reference to a. func4 (a) -- Passes a reference to a const a. 上面所有函数都可以通过a访问对象的成员以及方法。并且通常的C的继承和指针传递规则也使用。比如  void func5 (B b); void func6 (B* b); 在lua中调用  func5 (b) - Passes a copy of b, using Bs copy constructor. func6 (b) - Passes a pointer to b. func6 (a) - Error: Pointer to B expected. func1 (b) - Okay, b is a subclass of a. 当C给Lua传递的指针是NULL时LuaBridge会自动转换为nil代替。反之当Lua给C传递的nil相当于给C传递了一个NULL指针。
http://www.zqtcl.cn/news/651016/

相关文章:

  • 太原cms建站模板建设部网站监理注销查询
  • 流量对网站排名的影响因素网站内容的作用
  • 彩钢做网站能赚钱吗合肥市住房和城乡建设厅
  • 顺德网站建设itshunde罗村建网站
  • 网站开发语言开发十大免费货源网址
  • 网站建设要那些收费项如何做自己的淘客网站
  • 郴州文明网网站网站设计策划书3000字
  • 免费学习资源网站网站维护得多久
  • 电子商务网站建设考试重点长沙网站推广平台
  • 商业性质网站建设步骤佛山企业网站优化
  • 做网站投入网站设计与开发未来发展方向
  • 网站seo优化外包顾问网站ip解析
  • 贵阳建网站公司兼职网站推广如何做
  • 建设企业网站公司价格page做网站
  • 直播网站建设模板跨境电商选品
  • 购物网站有哪些shop++是什么
  • 自动化优化系统网站建设网站建设类文章
  • 网站建设以及推广提案书支付通道网站怎么做
  • 上海兼职做网站凤凰军事新闻
  • 青田建设局网站ui培训哪好
  • 佛山网站seo哪家好全返网站建设
  • 快速建站哪个平台好常见网页设计
  • 织梦网站地图模板网站服务费
  • 织梦建设两个网站 视频互联网公司排名1000
  • 广州企业网站设计西昌手机网
  • 一个工厂做网站有用吗wordpress重写登录页面
  • 网站服务器如何搭建网站分页设计
  • 可以直接进入网站的正能量连接温州注册网络公司
  • 清丰网站建设价格福州绿光网站建设工作室
  • 武城网站建设价格东莞容桂网站制作