上一篇在这 C++混合编程之idlcpp教程Lua篇(3)
与前面的工程相似,工程LuaTutorial2中,同样加入了三个文件 LuaTutorial2.cpp, Tutorial2.i, tutorial2.lua。其中LuaTutorial2.cpp的内容基本和LuaTutorial1.cpp雷同,不再赘述。 首先看一下Tutorial2.i的内容:
namespace tutorial
{
struct Point
{
float x;
float y;
meta:
Point();
Point(float a, float b);
$*
Point()
{}
Point(float a, float b)
{
x = a;
y = b;
}
*$
};
struct Rectangle
{
Point m_min;
Point m_max;
float left set get;
float right set get;
meta:
float bottom set get;
float top set get;
float area get;
float getArea();
all:
Rectangle(const Point ref min, const Point ref max);
Rectangle();
meta:
Rectangle(const Rectangle ref pt);
$*
void set_bottom(float bottom)
{
m_min.y = bottom;
}
float get_bottom()
{
return m_min.y;
}
void set_top(float top)
{
m_max.y = top;
}
float get_top()
{
return m_max.y;
}
float get_area()
{
return (m_max.x - m_min.x)*(m_max.y - m_min.y);
}
float getArea()
{
return (m_max.x - m_min.x)*(m_max.y - m_min.y);
}
*$
};
$*
inline Rectangle::Rectangle(const Point& min, const Point& max) : m_min(min), m_max(max)
{
}
inline Rectangle::Rectangle()
{}
inline float Rectangle::get_left()
{
return m_min.x;
}
inline void Rectangle::set_left(float left)
{
m_min.x = left;
}
inline float Rectangle::get_right()
{
return m_max.x;
}
inline void Rectangle::set_right(float right)
{
m_max.x = right;
}
*$
}
在这里仍然有 struct Point
与LuaTutorial1中的struct Point相比,除了原来的默认构造函数外,多了一个带两个参数的构造函数
Point(float a, float b);
两个构造函数都在meta: 段中,所以idlcpp不会在Tutorial2.h中生成对应的函数声明,所在直接在后面的$**$写上构造函数的实现代码,这些代码会插入到Tutorial2.h中的对应位置。当然也可以不使用meta:,这样的话这两个构造函数的声明部分就会出现在Tutorial2.h的struct Point中,那么实现代码就要写在外面了。
在struct Point后添加了一个新的类型struct Rectangle
前两行
Point m_min;
Point m_max;
声明了两个数据成员。
然后是
float left set get;
float right set get;
这里又出现了新的语法:属性。属性语法来自于C#。
形式为: 类型 + 名称 + 可选的set和get。在C++中实际上是生成了两个对应的成员函数,函数名分别为set_ + 属性名称,get_ + 属性名称,比如为属性left生成的两个成员函数为:
void set_left(float) 和 float get_left()。
然后还有三个属性的声明
float bottom set get;
float top set get;
float area get;
其中属性area是只读属性,即只生成float get_area()成员函数。
然后是
float getArea();
这是一个成员函数,在C++生成中的函数形式和这里是一样的。
然后是
Rectangle(const Point ref min, const Point ref max);
这是一个构造函数,这里出现了一个新的关键字ref。
关键字ref也来自于C#,相当于C++中函数参数声明中的&。
类似的还有一个关键字ptr,相当于C++中函数参数声明中的*。
之所以使用ref而不是& 是因为指针的缘故。在C++中指针的用法比较自由,在idlcpp中对指针的使用做了一定的限制,考虑到其中的差异,避免在移植现有C++代码到idl中出现遗漏,决定采用ptr代替*,为了看起来统一,同样也用ref取代了&。所以此处对应的C++代码为
Rectangle(const Point& min,const Point& max);
后面就是具体函数的实现代码。都放在$**$中以便复制到头文件中。
编译后生成的Tutorial2.h的内容如下:
//DO NOT EDIT THIS FILE, it is generated by idlcpp
//http://www.idlcpp.org
#pragma once
#include "./Tutorial2.h"
namespace tutorial{ struct Rectangle; }
namespace tutorial
{
struct Point
{
public:
float x;
float y;
public:
static Point* New();
static Point* New(float a,float b);
static Point* NewArray(unsigned int count);
Point()
{}
Point(float a, float b)
{
x = a;
y = b;
}
};
struct Rectangle
{
public:
Point m_min;
Point m_max;
void set_left( float);
float get_left();
void set_right( float);
float get_right();
Rectangle(const Point& min,const Point& max);
Rectangle();
public:
static Rectangle* New(const Point& min,const Point& max);
static Rectangle* New();
static Rectangle* NewArray(unsigned int count);
static Rectangle* Clone(const Rectangle& pt);
void set_bottom(float bottom)
{
m_min.y = bottom;
}
float get_bottom()
{
return m_min.y;
}
void set_top(float top)
{
m_max.y = top;
}
float get_top()
{
return m_max.y;
}
float get_area()
{
return (m_max.x - m_min.x)*(m_max.y - m_min.y);
}
float getArea()
{
return (m_max.x - m_min.x)*(m_max.y - m_min.y);
}
};
inline Rectangle::Rectangle(const Point& min, const Point& max) : m_min(min), m_max(max)
{
}
inline Rectangle::Rectangle()
{}
inline float Rectangle::get_left()
{
return m_min.x;
}
inline void Rectangle::set_left(float left)
{
m_min.x = left;
}
inline float Rectangle::get_right()
{
return m_max.x;
}
inline void Rectangle::set_right(float right)
{
m_max.x = right;
}
}
内容基本上都是和Tutorial2.i中一一对应的,在Point和Rectangle中各有几个静态函数,名字如下:New,Clone,NewArray。这些都是根据构造函数的形式生成的。这些函数的实现代码在Tutorial2.ic中。
编译后生成的Tutorial2.ic的内容如下:
//DO NOT EDIT THIS FILE, it is generated by idlcpp
//http://www.idlcpp.org
#pragma once
#include "Tutorial2.h"
#include "Tutorial2.mh"
#include "../../paf/src/pafcore/RefCount.h"
namespace tutorial
{
inline Point* Point::New()
{
return new Point();
}
inline Point* Point::New(float a,float b)
{
return new Point(a, b);
}
inline Point* Point::NewArray(unsigned int count)
{
return new_array<Point>(count);
}
inline Rectangle* Rectangle::New(const Point& min,const Point& max)
{
return new Rectangle(min, max);
}
inline Rectangle* Rectangle::New()
{
return new Rectangle();
}
inline Rectangle* Rectangle::NewArray(unsigned int count)
{
return new_array<Rectangle>(count);
}
inline Rectangle* Rectangle::Clone(const Rectangle& pt)
{
return new Rectangle(pt);
}
}
然后看一下脚本tutorial2.lua的内容:
rect1 = paf.tutorial.Rectangle();
rect1.m_min.x = 1;
rect1.m_min.y = 2;
print(rect1.left._);
print(rect1.bottom._);
rect1.right = 3;
rect1.top = 4;
print(rect1.m_max.x._);
print(rect1.m_max.y._);
print(rect1.area._);
rect2 = paf.tutorial.Rectangle(rect1.m_min, paf.tutorial.Point(5,5));
print(rect2:getArea()._);
rect3 = paf.tutorial.Rectangle.Clone(rect2);
print(rect3:getArea()._);
.
rect1 = paf.tutorial.Rectangle();
这是rect1 = paf.tutorial.Rectangle.New(); 的简化写法。
后面分别用数据成员和属性来操作rect1。
rect2 = paf.tutorial.Rectangle(rect1.m_min, paf.tutorial.Point(5,5));
调用了Rectangle带参数的构造函数(实际上是静态函数New)。
rect3 = paf.tutorial.Rectangle.Clone(rect2);
相当于C++中的 Rectangle* rect3 = new Rectangle(*rect2);
或者这一句可以利用lua的语法特点简写为 rect3 = rect2:Clone();
编译运行结果如下图:
原文:http://www.cnblogs.com/fdyjfd/p/5339439.html