PIDL

創建和設置

創建一個文件很簡單。 只需在 Visual Studio 中建立一個 txt 文件,將擴展名更改為 PIDL,然後將其設定為編譯即可。 擴展名為 PIDL 的檔案必須設定為「自訂建置」。

  1. Visual Studio 解決方案 Viewer

  2. 右鍵單擊已建立的PIDL文件

  3. 屬性 -> General -> Item Type: Custom Build Tool

PIDL語法

PIDL 具有以下結構。

global (namespace) 
         (訊息起始值ID) 
{ 
     函數聲明([in] 函數 Parameter, …) 
}

編譯時,會建立一個命名空間,並將存根和代理類別放置在該命名空間內。 所有 RMI 函數都有一個唯一的 ID,該值是透過在「訊息 ID 起始值」上加 +1 給出的。 但是,0 到 1,300 之間的 ID 以及 63,000 之後的 ID 用作 ProudNet 內部訊息,因此必須使用除這些之外的數字。

// 定義需要更改格式才能在 C# 中使用的變數。
rename cs(Proud::String, System.String);

global S2C 1000 
{
     // 定義Protocol。
    Chat([in] Proud::String txt);
}

如何使用生成的Proxy & Stub文件

當您執行 PIDL 時,將會建立以下六個檔案。

  • PIDL檔案名稱_common.Cpp

  • PIDL檔案名稱_common.h

  • PIDL檔案名稱_proxy.Cpp

  • PIDL檔案名稱_proxy.h

  • PIDL檔案名稱_stub.Cpp

  • PIDL檔案名稱_stub.h

對於 C#,將建立以下三個檔案。

  • PIDL檔案名稱_common.cs

  • PIDL檔案名稱_proxy.cs

  • PIDL檔案名稱_stub.cs

頭文件中#include h文件,cpp文件中#include cpp文件,排除普通文件,比較方便。 您可以在專案中包含 .h 文件和 .cpp 文件,但要小心,因為使用 Custom Build 會導致文件頻繁更改。 除了您定義的變數之外,還會自動將兩個參數新增至產生的 RMI 函數。

- 將Proxy連接到客戶端和伺服器

您必須先建立 PIDL 編譯輸出的 Proxy 實例,然後向 Proud.CNetClientProud.CNetServer 註冊該實例。 客戶端和伺服器都繼承了Proud.IRmiHost,可以透過這裡的AttachProxy方法註冊一個代理程式。 每個客戶端或伺服器可以有兩個或多個代理程式。 但是,訊息 ID 範圍不得重疊。

同樣在 C# 中,您可以在 NetServer 和 NetClient 中使用 AttachProxy 函數。

例如,假設有一個 TestA.Proxy 和一個 TestB.Proxy 連接到一個 CNetClient、 如果您聲明 TestA 的第一個消息 ID 爲 2,100,TestB 的第一個消息 ID 爲 2,200,那麼如果 TestA 中聲明的 RMI 函數數爲 200,分配給 TestA 的消息 ID 將介於 2,100 和 2,300 之間,從而導致 TestB 的消息 ID 重疊。如果所附代理的消息 ID 重疊,就會產生異常。

- 將Stub附加到客戶端和伺服器

// 使用 C++11 時
<exam.pidl>
Func1([in] int a, [in] string b);
 
<exam.cpp>
class Exam
{
    int x = 1;
 
    Exam::StubFunction examStub;
 
    void Main()
    {
        int y = 3;
        // PARAM_Exam_Func1 在 Exam_stub.h 中定義。
        examStub.Func1_Function = [this, y]PARAM_Exam_Func1 {
            x += a;
            y += a;
            return true;
        };
    }
};

PIDL 編譯結果的存根實例具有要透過網路接收的訊息作為虛擬函數執行的 RMI 函數。 在開發過程中,必須繼承該Stub類別並重寫RMI函數。

在 C# 中,您可以直接建立和使用 Stub 對象,而無需覆寫它。

對於 C++,PIDL 編譯器產生以下形式的宏觀,其中包裝了 RMI 函數名稱和參數,以方便開發人員。

#define DECRMI_S2C_ShowChat bool ShowChat(Proud::HostID remote,Proud::RmiContext &rmiContext,const CString &a,const int &b,const float &c)
#define DEFRMI_S2C_ShowChat(DerivedClass) bool DerivedClass::ShowChat(Proud::HostID remote,Proud::RmiContext &rmiContext,const CString &a,const int &b,const float &c)

- 宏觀使用順序

// 宏觀使用順序
// 1. 在繼承的Stub類別的類別聲明中加入DECRMI_namespace_method。
// 2. 在繼承的 Stub 類別的方法定義中使用 DEFRMI_namespace_method。

// 用法範例

// PIDL 檔案內容
global LobbyC2S 5000
{
    Foo([in] int a,[in] float b);
}
 
// 繼承LobbyC2S的stub並實作RMI的類
class LobbyC2SStub:public LobbyC2S::Stub
{
    DECRMI_LobbyC2S_Foo;
};
 
// RMI Foo在LobbyC2S中的例程實現
DEFRMI_LobbyC2S_Foo(LobbyC2SStub)
{
    // 這裡給的參數與PIDL的LobbyC2S.Foo的參數相同。
    a++;
    b++;
 
    return true;
}

用戶端和伺服器繼承 Proud.IRmiHost 並可透過其方法 Proud.IRmiHost.AttachStub 註冊存根。 與Proxy一樣,在訊息ID不重疊的情況下可以附加兩個或多個存根。

- 通訊Option Class

使用聲明為內部Static的變數很方便。

許多常用選項都是預先設定為靜態的。 您可以根據自己的方便自行建立並選擇所需的選項。

m_reliability: 選擇可靠且不可靠的通訊方式 m_encryptMode: 加密(根據速度和安全性,可以使用三個選項) m_compressMode: 是否壓縮

在 C# 中,使用以相同名稱定義的變數。


活用

Last updated