C++混合編程之idlcpp教程Python篇(5)

來源:互聯網
上載者:User

標籤:

上一篇在這  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;    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.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)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.