# PIDL

## Creating and setup

Creating the file is simple. Simply create the file in Visual Studio as a txt file, rename the extension to PIDL, and set it up for compilation. Files with the PIDL extension must be set to Custom Build.

> 1. Visual Studio solution Viewer
> 2. Right-click the PIDL file you created
> 3. <mark style="color:orange;">Properties</mark> -> <mark style="color:orange;">General</mark> -> <mark style="color:orange;">Item Type: Custom Build Tool</mark>

## PIDL syntax

The PIDL is structured as follows.

```
global (namespace) 
         (starting value of the message's ID) 
{ 
     Declaring function([in] function Parameter, …) 
}
```

When compiling, a namespace is created and the Stub and Proxy Class are placed within this namespace. All RMI functions have a unique ID, and this value is given by adding +1 from the ‘starting value of the message's ID’.\
However, ID between 0 and 1,300 and ID above 63,000 are used in ProudNet internal messages, so you must use other numbers.\ <br>

{% tabs %}
{% tab title="PIDL" %}

```cpp
// Define variables that need to be reformatted for use in C#.
rename cs(Proud::String, System.String);

global S2C 1000 
{
     // Define the Protocol.
    Chat([in] Proud::String txt);
}
```

{% endtab %}
{% endtabs %}

## How to use the generated Proxy & Stub file

When you run PIDL, it will generate six files as shown below.

* PIDLfile name\_Common.Cpp
* PIDLfile name\_Common.h
* PIDLfile name\_proxy.Cpp
* PIDLfile name\_proxy.h
* PIDLfile name\_stub.Cpp
* PIDLfile name\_stub.h

For C#, this will create 3 files as shown below.

* PIDLfile name\_common.cs
* PIDLfile name\_proxy.cs
* PIDLfile name\_stub.cs

\
It is convenient to #include each h file in the header and each cpp file in the cpp file, except for the Common file.\
You can include the .h and .cpp files in your project, but be aware that the files change frequently due to the use of Custom Build.\
The generated RMI function automatically adds two parameters in addition to the variables you define.<br>

### - Attach a proxy to a client and server

You must first create a Proxy instance of the PIDL compilation output and then register the instance with either <mark style="color:orange;">Proud.CNetClient</mark> or <mark style="color:orange;">Proud.CNetServer</mark>. Clients and servers inherit from <mark style="color:orange;">Proud.IRmiHost</mark> and can register a proxy with it via the method <mark style="color:orange;">AttachProxy</mark>. \
Each client or server can attach more than one Proxy. However, the range of message IDs must not overlap.

{% hint style="info" %}
Similarly in C#, you can use the <mark style="color:orange;">AttachProxy</mark> function found in NetServer and NetClient.
{% endhint %}

For example, if you have TestA.Proxy and TestB.Proxy attached to a single <mark style="color:orange;">CNetClient</mark>, and you declare the first message ID of TestA to be 2,100 and the first message ID of TestB to be 2,200, if the number of RMI functions declared in TestA is 200, the message ID assigned to TestA will be between 2,100 and 2,300, causing the message IDs of TestB to overlap. If the message IDs of the attached proxies overlap, an exception is thrown.

### -  Attach a stub to a client and server

{% tabs %}
{% tab title="C++11" %}

```cpp
// If you are using 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 is a define defined in Exam_stub.h.
        examStub.Func1_Function = [this, y]PARAM_Exam_Func1 {
            x += a;
            y += a;
            return true;
        };
    }
};
```

{% endtab %}

{% tab title="C#" %}

```csharp
<exam.pidl>
Func1([in] int a, [in] string b);
 
<exam.cs>
class Exam
{
    int x = 1;
 
    Exam.Stub examStub = new Exam.Stub();
 
    void Main()
    {
        int y = 3;
        
        examStub.Func1 = (a, b) => {
            x += a;
            y += a;
            
            return true;
        };
    }
}
```

{% endtab %}
{% endtabs %}

The Stub instance of the PIDL compilation result has the RMI functions to be executed by messages received over the network as virtual function. When developing, you must inherit this Stub class and override the RMI functions.

{% hint style="info" %}
In C#, you can create and use the Stub object directly without any overrides.
{% endhint %}

For the convenience of C++ developers, the PIDL compiler generates the following types of macros, packaged with RMI function names and parameters.

```
#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)
```

### - Order of macro

{% tabs %}
{% tab title="C++" %}

```cpp
// Order of macro use
// 1. In the class declaration of the inherited Stub class, add the DECRMI_Namespace_Method.
// 2. Use DEFRMI_Namespace_Method in the method definition of the inherited Stub class.

// Usage examples

// PIDL file content
global LobbyC2S 5000
{
    Foo([in] int a,[in] float b);
}
 
// Classes that inherit from LobbyC2S's stub to implement RMI
class LobbyC2SStub:public LobbyC2S::Stub
{
    DECRMI_LobbyC2S_Foo;
};
 
// Implementing Routines in RMI Foo in LobbyC2S
DEFRMI_LobbyC2S_Foo(LobbyC2SStub)
{
    // The parameters given here are the same as those in LobbyC2S.Foo in the PIDL.
    a++;
    b++;
 
    return true;
}

```

{% endtab %}
{% endtabs %}

Clients and servers inherit from <mark style="color:orange;">Proud.IRmiHost</mark> and can register a stub via the method <mark style="color:orange;">Proud.IRmiHost.AttachStub</mark> in it. As with proxies, more than one stub can be attached as long as the message IDs do not overlap.<br>

### **-** Option Class for Communication

It is convenient to use variables declared as internal static.

<table><thead><tr><th width="202">C++</th><th width="256">C#</th><th>Description</th></tr></thead><tbody><tr><td>Proud::HostID</td><td>Nettention.Proud.HostID</td><td>The ID of the host you want to communicate with</td></tr><tr><td>Proud::RmiContext</td><td>Nettention.Proud.RmiContext</td><td>Options for sending or receiving</td></tr></tbody></table>

<table><thead><tr><th width="274">Reliable / Unreliable Communication name</th><th>Description</th></tr></thead><tbody><tr><td>ReliableSend</td><td>Reliable communication</td></tr><tr><td>FastEncryptedReliableSend</td><td>Reliable communication using fast encryption method (less secure)</td></tr><tr><td>SecureReliableSend</td><td>Encrypted reliable communication</td></tr><tr><td>UnreliableSend</td><td>Unreliable communication</td></tr><tr><td>FastEncryptedUnreliableSend</td><td>Unreliable communication using fast encryption method (less secure)</td></tr><tr><td>SecureUnreliableSend</td><td>Encrypted unreliable communication</td></tr></tbody></table>

The most commonly used options are pre-built as Static. You can create your own options to suit your needs.

> <mark style="color:orange;">m\_reliability</mark>: Selecting Reliable & Unreliable communication methods\ <mark style="color:orange;">m\_encryptMode</mark>: Whether to encrypt (there are three options, depending on speed and security)\ <mark style="color:orange;">m\_compressMode</mark>: Whether to compress

{% hint style="info" %}
In C#, use a variable defined with the same name.
{% endhint %}

***

## Usage

{% content-ref url="/pages/dIZcRXCNxvzDk80MDuW7" %}
[Utilization of PIDL](/proudnet.eng/proudnet/using_pn/pidl/using_pidl.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.proudnet.com/proudnet.eng/proudnet/using_pn/pidl.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
