C++混合编程之idlcpp教程Lua篇(5)

上一篇在这 C++混合编程之idlcpp教程Lua篇(4)

第一篇在这 C++混合编程之idlcpp教程(一)

与前面的工程相似,工程LuaTutorial3中,同样加入了三个文件:LuaTutorial3.cpp, Tutorial3.i, tutorial3.lua 。其中LuaTutorial3.cpp的内容基本和LuaTutorial2.cpp雷同,不再赘述。

首先看一下Tutorial3.i的内容:

namespace tutorial
{
    struct Point
    {
        float x;
        float y;
    meta:
        Point();
        Point(float a, float b);
        Point(const Point ref pt);

        $*
        Point()
        {}
        Point(float a, float b)
        {
            x = a;
            y = b;
        }
        *$
    };

    struct Shape
    {
        abstract float getArea();
        $$        virtual ~Shape() {}
    };

    struct Triangle : Shape
    {
        Point m_vertices[$3];
    meta:
        static Triangle new New();
        $*
            virtual float getArea()
        {
            return fabs(m_vertices[0].x * m_vertices[1].y
                + m_vertices[1].x * m_vertices[2].y
                + m_vertices[2].x * m_vertices[0].y
                - m_vertices[0].x * m_vertices[2].y
                - m_vertices[1].x * m_vertices[0].y
                - m_vertices[2].x * m_vertices[1].y) * 0.5;
        }
        static Triangle* New()
        {
            return new Triangle;
        }
        *$
    };

}

在这里仍然有struct Point。 引入了基类 struct Shape。其中这一行

abstract float getArea();

表示声明一个纯虚函数,相当于C++中的

virtual float getArea() = 0;

如果不是纯虚函数,使用关键字virtual代替abstract即可。

新加入了类型 Triangle

struct Triangle : Shape

与C++一样,用 : 表示继承。因idlcpp表示的是接口信息,所以只有公有继承。与C++不同,idlcpp并没有public, protected, private这三个关键字。

然后是数据成员m_vertices;

Point m_vertices[$3];

idlcpp只关心接口的信息,在其语法分析部分,只能看见Point m_vertices[]。数字3需要用插入代码的方式。其中$表示直接连在后面的一个标识符或整数(实际上是由字母,下划线和数字组成的串)将插入到生成的C++头文件对应的位置上。下两行

meta:

static Triangle new New();

声明了一个名为New的静态函数,其实现代码就在后续的类型声明内,所以此处用meta阻止在头文件中生成函数声明,如前所述,idlcpp如果看见了构造函数的声明,会生成静态函数New,所以此时不能出现构造函数的声明,以免名字冲突。对照一下后面实现部分的C++声明

static Triangle* New()

这里和C++不一致的地方是少了一个*并且多了一个new。new是idlcpp中的一个关键字,放在函数返回值类型与函数名之间,表示函数内部以new的形式创建了一个对象,返回其指针,外界需要用delete的形式删除它(还有另一种关于引用计数的情况,暂不讨论)。在脚本语言中一般自带垃圾收集机制,脚本语言自动管理内存的分配释放。程序员一般不用关心何时删除对象这样的问题,而在C++中在堆上分配对象的生命期一般由程序员维护。为处理其间的差异,idlcpp在函数声明的返回值类型部分有如下几种形式:


idlcpp声明


C++声明


实现


typeName


typeName


返回值


typeName ref


typeName&


返回引用


typeName ptr


typeName*


返回指针


typeName new


typeName*


返回指针,外界需要delete,或者增加了引用计数,外界需要release


typeName new []


typeName*


返回指针,外界需要delete[]

例如下面的C++代码:

int g_a;
int* getGlobal()
{
    return &g_a;
}

int* getNew()
{
    return new int;
}

int* getNewArray(int count)
{
    return new int[count];
}

三个函数的返回值类型都是int*,但对于后面两个,分别要用delete 和delete[]释放内存,就语法层面看,从函数的声明不能区分这些情况。只能由程序员根据实际情况进行不同的处理。而在脚本语言中并不希望看到显示的删除对象的调用。所以idlcpp通过语法层面的声明,在生成的元数据代码中进行区分,然后由运行时库(pafcore.dll)进行处理。

编译后生成的Tutorial3.h的内容如下:

//DO NOT EDIT THIS FILE, it is generated by idlcpp
//http://www.idlcpp.org

#pragma once

#include "./Tutorial3.h"
namespace tutorial{ struct Triangle; }

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);
        static Point* Clone(const Point& pt);

        Point()
        {}
        Point(float a, float b)
        {
            x = a;
            y = b;
        }

    };

    struct Shape
    {
    public:

        virtual float getArea() = 0 ;
        virtual ~Shape() {}
    };

    struct Triangle : public Shape
    {
    public:

        Point m_vertices[3];

            virtual float getArea()
        {
            return fabs(m_vertices[0].x * m_vertices[1].y
                + m_vertices[1].x * m_vertices[2].y
                + m_vertices[2].x * m_vertices[0].y
                - m_vertices[0].x * m_vertices[2].y
                - m_vertices[1].x * m_vertices[0].y
                - m_vertices[2].x * m_vertices[1].y) * 0.5;
        }
        static Triangle* New()
        {
            return new Triangle;
        }

    };

}

内容基本上都是和Tutorial3.i中一一对应的。然后看一下脚本tutorial3.lua的内容:

triangle = paf.tutorial.Triangle();
triangle.m_vertices[0] = paf.tutorial.Point(0,0);
triangle.m_vertices[1] = paf.tutorial.Point(0,1);
triangle.m_vertices[2] = paf.tutorial.Point(1,1);

print(triangle:getArea()._);

创建了一个tirangle对象,然后设置数据成员,此处运行时能够检测下标的范围为0至2,如果超出范围将会报错,最后调用其基类Shape中声明的函数getArea(),因为这是虚函数,所以最终会调用到Traingle::getArea()。

编译运行结果如下图:

时间: 2024-10-07 06:32:56

C++混合编程之idlcpp教程Lua篇(5)的相关文章

C++混合编程之idlcpp教程Lua篇(4)

上一篇在这  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();

C++混合编程之idlcpp教程Lua篇(8)

上一篇在这 C++混合编程之idlcpp教程Lua篇(7) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程LuaTutorial6中,同样加入了四个文件:LuaTutorial6.cpp, Tutorial6.cpp, Tutorial6.i, tutorial6.lua.其中LuaTutorial6.cpp的内容基本和LuaTutorial5.cpp雷同,不再赘述. 首先看一下Tutorial6.i的内容: namespace tutorial { template

C++混合编程之idlcpp教程Lua篇(9)

上一篇在这 C++混合编程之idlcpp教程Lua篇(8) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相比,工程LuaTutorial7中除了四个文件LuaTutorial7.cpp, Tutorial7.cpp, Tutorial7.i, tutorial7.lua 外,Tutorial6.cpp也被加入了此工程中.其中LuaTutorial7.cpp的内容基本和LuaTutorial6.cpp雷同,不再赘述. 首先看一下Tutorial7.i的内容: #import "

C++混合编程之idlcpp教程Lua篇(7)

上一篇在这 C++混合编程之idlcpp教程Lua篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与LuaTutorial4工程相似,工程LuaTutorial5中,同样加入了四个文件:LuaTutorial5.cpp, Tutorial5.cpp, Tutorial5.i, tutorial5.lua.其中LuaTutorial5.cpp的内容基本和LuaTutorial4.cpp雷同,不再赘述. 首先看一下Tutorial5.i的内容: #import "../../paf/s

C++混合编程之idlcpp教程Lua篇(2)

在上一篇 C++混合编程之idlcpp教程(一) 中介绍了 idlcpp 工具的使用.现在对 idlcpp 所带的示例教程进行讲解,这里针对的 Lua 语言的例子.首先看第一个示例程序 LuaTutorial0.像很多语言的第一个例子一样,是一个打印 Hello world 的程序.用Visual Studio 2015打开解决方案文件 tutorials\LuaTutorials\LuaTutorials.sln,其下已经有多个工程文件. 在工程LuaTutorial0中,已经加入了三个文件,

C++混合编程之idlcpp教程Python篇(7)

上一篇在这 C++混合编程之idlcpp教程Python篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与PythonTutorial4工程相似,工程PythonTutorial5中,同样加入了四个文件:PythonTutorial5.cpp, Tutorial5.cpp, Tutorial5.i, tutorial5.py.其中PythonTutorial5.cpp的内容基本和PythonTutorial4.cpp雷同,不再赘述.首先看一下Tutorial5.i的内容: #imp

C++混合编程之idlcpp教程Python篇(8)

上一篇在这 C++混合编程之idlcpp教程Python篇(7) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial6中,同样加入了四个文件:PythonTutorial6.cpp, Tutorial6.cpp, Tutorial6.i, tutorial6.py.其中PythonTutorial6.cpp的内容基本和PythonTutorial5.cpp雷同,不再赘述.首先看一下Tutorial6.i的内容: #import "../../p

C++混合编程之idlcpp教程Python篇(4)

上一篇在这 C++混合编程之idlcpp教程Python篇(3) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial2中,同样加入了三个文件 PythonTutorial2.cpp, Tutorial2.i, tutorial2.py.其中PythonTutorial2.cpp的内容基本和PythonTutorial1.cpp雷同,不再赘述.首先看一下Tutorial2.i的内容: namespace tutorial { struct Poi

C++混合编程之idlcpp教程Python篇(3)

上一篇 C++混合编程之idlcpp教程Python篇(2) 是一个 hello world 的例子,仅仅涉及了静态函数的调用.这一篇会有新的内容. 与PythonTutorial0相似,工程PythonTutorial1中,同样加入了三个文件 PythonTutorial1.cpp, Tutorial1.i, tutorial1.py 其中PythonTutorial1.cpp的内容基本和PythonTutorial0.cpp雷同,不再赘述. 首先看一下Tutorial1.i的内容: name