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

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

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

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

namespace tutorial
{
struct Point
{
float x;
float y;
nocode Point();
nocode Point(float a, float b);
nocode Point(const Point& pt); #{
Point()
{}
Point(float a, float b)
{
x = a;
y = b;
}
#}
}; struct Shape
{
abstract float getArea();
## virtual ~Shape() {}
}; struct Triangle : Shape
{
Point m_vertices[#];
nocode static Triangle+ New();
#{
virtual float getArea()
{
return fabs(m_vertices[].x * m_vertices[].y
+ m_vertices[].x * m_vertices[].y
+ m_vertices[].x * m_vertices[].y
- m_vertices[].x * m_vertices[].y
- m_vertices[].x * m_vertices[].y
- m_vertices[].x * m_vertices[].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++头文件对应的位置上。下一行

nocode static Triangle+ New();

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

static Triangle* New()

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

idlcpp声明

C++声明

实现

typeName

typeName

返回值

typeName &

typeName&

返回引用

typeName *

typeName*

返回指针

typeName +

typeName*

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

typeName +[]

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;

     Point()
{}
Point(float a, float b)
{
x = a;
y = b;
} }; struct Shape
{
public: virtual float getArea() = ;
virtual ~Shape() {}
}; struct Triangle : public Shape
{
public: Point m_vertices[]; virtual float getArea()
{
return fabs(m_vertices[].x * m_vertices[].y
+ m_vertices[].x * m_vertices[].y
+ m_vertices[].x * m_vertices[].y
- m_vertices[].x * m_vertices[].y
- m_vertices[].x * m_vertices[].y
- m_vertices[].x * m_vertices[].y) * 0.5;
}
static Triangle* New()
{
return new Triangle;
} }; }

内容基本上都是和Tutorial3.i中一一对应的。

然后看一下脚本tutorial3.py的内容:

import pafpython;
paf = pafpython.paf; 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()。

编译运行结果如下图:

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

  1. C++混合编程之idlcpp教程Python篇(9)

    上一篇在这 C++混合编程之idlcpp教程Python篇(8) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相比,工程PythonTutorial7中除了四个文件PythonTu ...

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

    上一篇在这 C++混合编程之idlcpp教程Python篇(7) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial6中,同样加入了四个文件:Pyt ...

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

    上一篇在这 C++混合编程之idlcpp教程Python篇(6) 第一篇在这 C++混合编程之idlcpp教程(一) 与PythonTutorial4工程相似,工程PythonTutorial5中,同 ...

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

    上一篇在这 C++混合编程之idlcpp教程Python篇(5) 第一篇在这 C++混合编程之idlcpp教程(一) 工程PythonTutorial4中加入了四个文件:PythonTutorial4 ...

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

    上一篇在这 C++混合编程之idlcpp教程Python篇(3) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相似,工程PythonTutorial2中,同样加入了三个文件 Pyt ...

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

    上一篇 C++混合编程之idlcpp教程Python篇(2) 是一个 hello world 的例子,仅仅涉及了静态函数的调用.这一篇会有新的内容. 与PythonTutorial0相似,工程Pyth ...

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

    在上一篇 C++混合编程之idlcpp教程(一) 中介绍了 idlcpp 工具的使用.现在对 idlcpp 所带的示例教程进行讲解,这里针对的 Python 语言的例子.首先看第一个示例程序 Pyth ...

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

    上一篇在这 C++混合编程之idlcpp教程Lua篇(5) 第一篇在这 C++混合编程之idlcpp教程(一) 工程LuaTutorial4中加入了四个文件:LuaTutorial4.cpp, Tut ...

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

    上一篇在这 C++混合编程之idlcpp教程Lua篇(8) 第一篇在这 C++混合编程之idlcpp教程(一) 与前面的工程相比,工程LuaTutorial7中除了四个文件LuaTutorial7.c ...

随机推荐

  1. 实现type函数用于识别标准类型和内置对象类型

    function type(obj){ return Object.prototype.toString.call(obj).slice(8,-1); } var t=type(new Number( ...

  2. 十大开源的.NET用户界面框架 让GUI设计不再犯难

    选择一款合适的GUI框架是.NET开发中比较重要但又很棘手的问题,因为用户界面相当于一款应用的"门面",直接面向用户.好的UI更能吸引用户,有时甚至成为决定一款应用成败的关键.下面 ...

  3. jQueryAjax笔记

    ajax优点:能在不刷新整个页面的前提下更新数据,使用户操作与服务器响应异步化. ajax缺点:破坏浏览器“前进”.“后退”按钮的正常功能,搜索引擎爬虫不能理解那些奇怪的JS代码和因此引起的页面内容的 ...

  4. shell常用命令

    wget wget -P /root url -O rename 实现文件下载指定目录和重命名

  5. ncurses-devel

    :Install ncurses(ncurses-devel) and try again. 做一个简单的铺垫,ncurses是字符终端下屏幕控制的基本库.可能很多新开发的程序已经不再使用.假如要编译 ...

  6. Python list列表的排序

    当我们从数据库中获取一写数据后,一般对于列表的排序是经常会遇到的问题,今天总结一下python对于列表list排序的常用方法: 第一种:内建函数sort() 这个应该是我们使用最多的也是最简单的排序函 ...

  7. ubuntu与win10互换硬盘

    实例:将sdb上的ubuntu转移至sda,将sda上的win转移至sdb1. 备份资料2. 制作老毛桃PE盘3. 格式化sda4. dd if=/dev/sdb of=/dev/sda ,将sdb克 ...

  8. 运用requirejs的异步加载方式

    很容易让人以为是权重出问题了,但就我自己多个项目动画导出的经验来看,大 我们说程序员核心能力有以下几点:自学能力,解决问题的能力,团队合作能力.自学可以让我们在这个日新月异的时代不被淘汰;解决问题可以 ...

  9. android书籍

    教程 源码下载 高薪招聘 Cocos2d-x 博客 签到 视频教程 wiki     帖子 搜索 热搜:二维码定时器手电筒滑块斗地主书架定位买手机聊天游戏开发游戏股票查询机顶盒通话记录二维码扫描振动器 ...

  10. SmartUpload实现文件上传时file和表单文本同时提交的问题

    JSP页面: <%@ page language="java" import="java.util.*" pageEncoding="UTF-8 ...