PIDL

생성 및 셋팅

파일을 생성하는 방법은 간단합니다. Visual Studio에서 txt 파일로 파일을 생성하고, 확장자를 PIDL로 바꾼 후 컴파일을 위한 세팅을 해주시면 됩니다. 확장자가 PIDL인 파일들은 Custom Build 설정되어 있어야 합니다.

  1. Visual Studio 솔루션 Viewer

  2. 생성한 PIDL 파일 우 클릭

  3. 속성 -> General -> Item Type: Custom Build Tool

PIDL 문법

PIDL은 아래와 같은 구조로 이루어져 있습니다.

global (namespace) 
         (메시지의 ID 첫 시작 값) 
{ 
     함수 선언([in] 함수 Parameter, …) 
}

컴파일을 하게 되면 namespace를 생성 후, Stub과 Proxy Class는 이 namespace 안에 들어가게 됩니다. 모든 RMI함수들은 고유ID를 갖게 되는데 이 값은 ‘메시지의 ID 첫 시작 값’ 으로부터 +1씩 추가되어 ID가 부여됩니다. 단, 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을 실행하시면 아래와 같은 6개의 파일이 생성됩니다.

  • PIDL파일명_common.Cpp

  • PIDL파일명_common.h

  • PIDL파일명_proxy.Cpp

  • PIDL파일명_proxy.h

  • PIDL파일명_stub.Cpp

  • PIDL파일명_stub.h

C#의 경우 아래와 같은 3개의 파일이 생성됩니다.

  • PIDL파일명_common.cs

  • PIDL파일명_proxy.cs

  • PIDL파일명_stub.cs

common 파일을 제외한 각각 h파일은 header에, cpp파일은 cpp파일에 #include 해주면 편리합니다. .h파일과 .cpp 파일은 프로젝트에 포함시켜도 되지만, Custom Build 사용으로 인하여 파일 변경이 자주 일어나므로 주의합니다. 생성된 RMI 함수에는 정의한 변수 외에 두 가지 파라미터가 자동으로 추가됩니다.

- 클라이언트,서버에 Proxy 붙이기

PIDL 컴파일 결과물의 Proxy 인스턴스를 먼저 생성한 후 인스턴스를 Proud.CNetClient Proud.CNetServer에 등록해야 합니다. 클라이언트와 서버는 Proud.IRmiHost 를 상속받았으며, 여기에 있는 메서드 AttachProxy 를 통해 proxy를 등록할 수 있습니다. 클라이언트나 서버 각각은 Proxy는 두개 이상을 붙여도 됩니다. 단, 메시지 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가 겹치게 됩니다. 붙이는 Proxy의 메시지 ID가 겹치게 될 경우 예외가 throw됩니다.

- 클라이언트,서버에 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에 정의되어 있는 define 입니다.
        examStub.Func1_Function = [this, y]PARAM_Exam_Func1 {
            x += a;
            y += a;
            return true;
        };
    }
};

PIDL 컴파일 결과물의 Stub 인스턴스는 네트워크로 수신된 메시지에 의해 실행될 RMI 함수들을 virtual function으로 갖고 있습니다. 개발 시에는 이 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 클래스의 class 선언에서 DECRMI_네임스페이스_메서드 를 추가합니다.
// 2. 상속된 Stub 클래스의 메서드 정의에서 DEFRMI_네임스페이스_메서드 를 사용합니다.

// 사용 예시

// PIDL 파일 내용
global LobbyC2S 5000
{
    Foo([in] int a,[in] float b);
}
 
// LobbyC2S의 Stub을 상속받아 RMI를 구현하는 클래스
class LobbyC2SStub:public LobbyC2S::Stub
{
    DECRMI_LobbyC2S_Foo;
};
 
// LobbyC2S의 RMI Foo의 루틴 구현
DEFRMI_LobbyC2S_Foo(LobbyC2SStub)
{
    // 여기에서 주어지는 파라메터는 PIDL 의 LobbyC2S.Foo 의 파라메터와 동일합니다.
    a++;
    b++;
 
    return true;
}

클라이언트와 서버는 Proud.IRmiHost를 상속 받았으며, 여기에 있는 메서드 Proud.IRmiHost.AttachStub 을 통해 stub을 등록할 수 있습니다. Proxy와 마찬가지로 메시지 ID가 겹치지 않는 조건 하에 2개 이상의 Stub을 붙일 수 있습니다.

- 통신을 위한 Option Class

내부 Static으로 선언된 변수들을 사용하면 편리합니다.

많이 사용하는 Option 은 Static으로 미리 만들어져 있습니다. 사용자 편의에 따라 직접 생성하여 원하시는 Option을 정할 수 있습니다.

m_reliability: Reliable & Unreliable 통신 방식 선택 m_encryptMode: 암호화 여부(속도와 보안성에 따라 세가지 Option 선택이 가능합니다.) m_compressMode: 압축 여부

C#의 경우 같은 이름으로 정의되어 있는 변수를 사용합니다.


활용

Last updated