上一篇在这  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. APP如何实现推送功能

    一.推送功能的集成 (1)在Umeng开发者中心,申请新应用,开通推送功能.此时需要上传开发推送证书和生产推送证书的p12文件. 申请证书的流程如下: >>1 创建开发推送证书 >& ...

  2. [刘阳Java]_MyBatis_映射文件的resultMap标签入门_第4讲

    <resultMap>:用于解决实体类中属性和表字段名不相同的问题 id:表示当前<resultMap>标签的唯一标识 result:定义表字段和实体类属性的对应关系 prop ...

  3. DOM事件机制进一步理解

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  4. Java Reflection

    Java语言的反射机制 1. Java反射的含义:获取应用中正在运行的Java对象. 2. Java反射机制: 在运行的程序中,对于任意的类,都可以知道这个类的属性.方法以及构造函数,对于任意对象都可 ...

  5. Yii2 中日志的记录

    Yii2自带日志记录,但用起来感觉比较不是很顺手,故自己封装了个方法,如下: /** * 记录日志 * * @param type $msg * @time 2015年8月31日17:46:20 * ...

  6. 关于KB905474正版验证补丁破解办法 KB905474是个微软操作系统正版/盗版监测间谍软件。更新安装后,右下角有个提示说“系统监测到你的操作系统是盗版”。 如果没有安装的: 在系统提示更新的时候注意看一下,如果包含有“更新KB905474”就去掉“更新KB905474”方框前的勾,点击关闭(注意如果没有去掉那个勾得话,会找不到“关闭”,而是“确定”),在不在提示我该消息前打勾。 如果已经安装

    关于KB905474正版验证补丁破解办法 KB905474是个微软操作系统正版/盗版监测间谍软件.更新安装后,右下角有个提示说“系统监测到你的操作系统是盗版”. 如果没有安装的: 在系统提示更新的时候 ...

  7. 远程debug hadoop

  8. php框架制做笔记

    在学习完基础之后,最好的提高方式是做一个自己的框架,因为框架会用到各个知识点,在制做过程中,复习,巩固,提高. 在框架中,因为是单入口,整个脚本运行时都存在的变量我们应该设为静态变量,这样它在每个地方 ...

  9. 从0到1搭建移动App功能自动化测试平台(2):操作iOS应用的控件

    转自:http://debugtalk.com/post/build-app-automated-test-platform-from-0-to-1-Appium-interrogate-iOS-UI ...

  10. Kiwi iOS驱动测试开发

    Kiwi是iOS开发一个行为驱动开发库.目标是提供一个BDD库,精美的简单安装和使用. 安装 使用CocoaPods安装: pod 'Kiwi'如果使用Xcode5则使用: pod 'Kiwi/XCT ...