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 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。与PythonTutorial1中的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.py的内容:

 

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

编译运行结果如下图:

 

C++混合编程之idlcpp教程Python篇(4)_第1张图片

 

你可能感兴趣的:(C++混合编程之idlcpp教程Python篇(4))