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

来源:http://www.cnblogs.com/fdyjfd/archive/2016/04/04/5352765.html
-Advertisement-
Play Games

上一篇在這 C++混合編程之idlcpp教程Lua篇(4) 第一篇在這 C++混合編程之idlcpp教程(一) 與前面的工程相似,工程LuaTutorial3中,同樣加入了三個文件:LuaTutorial3.cpp, Tutorial3.i, tutorial3.lua 。其中LuaTutorial ...


上一篇在這 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()。

編譯運行結果如下圖:

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1,.NET Framework:是開發平臺,包含兩大部分: ①龐大的代碼庫(類庫),可以在客戶語言(C#,VB)中來使用這些代碼 ②Common Language Runtime,負責管理應用程式的執行 2,使用.NET Framework編寫應用程式,就是使用.NET 代碼庫編寫程式。 3,C# ...
  • 0x00 前言 關於TDD測試驅動開發的文章已經有很多了,但是在游戲開發尤其是使用Unity3D開發游戲時,卻聽不到特別多關於TDD的聲音。那麼本文就來簡單聊一聊TDD如何在U3D項目中使用以及如何使用U3D 5.3.X之後版本已經集成的單元測試模塊Editor Test Runner。 0x01 ...
  • 為什麼要以對象的方式來訪問xml數據表? 還記得,自己是在一次完成師兄佈置的任務時接觸到了xml,那時候需要用xml來作為數據文件,保存一個簡單的圖書管理系統的數據。於是就知道了,可以用xml文件來保存數據(而且比用簡單的文本文件保存數據規範的多,在訪問與讀取數據上面都十分方便),就這樣使用xml的 ...
  • 1.需求 寫一個基於memcache的cache模塊, 需要在key前面加上特定的首碼, 所以user cache的原始的store函數應該寫成 由於加首碼的操作(key_encode/1)是所有存入cache前必須要做的事, 所以我們可以考慮通過metaprogramming來定義一個行為叫bef ...
  • 虛擬機類載入機制 虛擬機把描述的類的數據從class文件載入到記憶體後,並對數據進行校驗,轉換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是虛擬機的類載入機制。 虛擬機類載入機制 虛擬機把描述的類的數據從class文件載入到記憶體後,並對數據進行校驗,轉換解析和初始化,最終形成可以被虛 ...
  • 先來完成一個將輸入數據轉換成json格式輸出的小任務 有意思的是,我們可以直接將一個配置好的經緯度文件通過程式直接生成json文件,這是gpsdata.csv文件里的數據 通過程式直接運行,在程式同目錄中生成了output.json文件 為什麼會這樣呢? 在用scanf()從鍵盤讀取數據、print ...
  • 啥也不說了,直接上源碼 #! /usr/bin/env python #coding=utf-8 import os import md5 import time def getmd5( filename ): ''' 形參:文件名 返回:文件的MD5碼 ''' file = open( filen ...
  • C++ 日期 & 時間 C++ 標準庫沒有提供所謂的日期類型。C++ 繼承了 C 語言用於日期和時間操作的結構和函數。為了使用日期和時間相關的函數和結構,需要在 C++ 程式中引用 <ctime> 頭文件。 有四個與時間相關的類型:clock_t、time_t、size_t 和 tm。類型 cloc ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...