17.Marshalling user-defined types in C# language

Instructions for putting custom object types in RMI's parameters are given in Dealing with The C # language also makes this possible.

I will explain it using an example. The example is like this.

When C++ side sends a serialized CFastArray, C# side will deserialize and use it.

The explanation proceeds to the 5 steps listed below.

  1. Making C# Student Class

  2. Making C++ CStudent Class

  3. Making PIDL files

  4. Making C++ marshalling code

  5. Makingi C# marshalling code

A simple example to write in this explanation is an example that when a C # client calls RMI called Ping, the C ++ server that receives it passes StudentList RMI to pass C ++ 's CFastArray to C #, and the C # side receives it as a List.

17.1C# Student Class

namespace CsClient
{
    class Student
    {
        public string Name;
        public int ID;
        public int Kor;
        public int Eng;
        public int Mat;
        public override string ToString()
        {
            return string.Format("Name: {0}({1}) K: {2}, E: {3}, M: {4}", Name, ID, Kor, Eng, Mat);
        }
    }
} 

17.2Making C++ CStudent Class

class CStudent
{
    public:
    String Name;
    int ID;
    int Kor;
    int Eng;
    int Mat;
}; 

Class to be used in C ++ server.

17.3Making PIDL files

rename cs(Proud::CFastArray<CStudent>, System.Collections.Generic.List<CsClient.Student>);
[marshaler(cs)=CsClient.MyMarshaler]
global S2C 3000
{
    StudentList([in] Proud::CFastArray<CStudent> students);
} 

C2S.PIDL

[marshaler(cs)=CsClient.MyMarshaler]
global C2S 4000
{
    Ping([in] int value);
} 

This example PIDL code sends a StudentList when a client sends a ping.

Build this PIDL code for generating .h, .cpp, .cs files.

17.4Making C++ marshalling code

Making marshaller

namespace Proud
{
    CMessage& operator >> (CMessage& msg, CStudent student)
    {
        msg >> student.Name >> student.ID >> student.Kor >> student.Eng >> student.Mat;
        return msg;
    }
    CMessage& operator << (CMessage& msg, const CStudent& student)
    {
        msg << student.Name << student.ID << student.Kor << student.Eng << student.Mat;
        return msg;
    }
} 

This is the code to marshal the CStudent class created as an example.

For more information, Please refer to this link. http://guide.nettention.com/cpp_en#collection_marshal

C2SStub

class C2SStub : public C2S::Stub
{
    public:
    DECRMI_C2S_Ping;
};

DEFRMI_C2S_Ping(C2SStub)
{
    {
        CriticalSectionLock(g_lock, true);
        g_S2CProxy.StudentList(remote, RmiContext::ReliableSend, g_Students);
    }
    return true;
}
C2SStub g_C2SStub; 

This is the code that sends StudentList when Ping is sent from C # client.

17.5Making C# marshalling code

Making marshaller

namespace CsClient
{
    class MyMarshaler : Nettention.Proud.Marshaler
    {
        public static bool Read(Message msg, out List<Student> students)
        {
            students = null;
            int size = 0;
            if (!msg.ReadScalar(ref size))
            {
                return false;
            }
            students = new List<Student>();
            for (int i = 0; i < size; ++i)
            {
                Student s = new Student();
                if (!msg.Read(out s.Name)) { return false;
                }
                if (!msg.Read(out s.ID))
                {
                    return false;
                }
                if (!msg.Read(out s.Kor))
                {
                    return false;
                }
                if (!msg.Read(out s.Eng))
                {
                    return false;
                }
                if (!msg.Read(out s.Mat))
                {
                    return false;
                }
                students.Add(s);
            }
            return true;
        }

        public static void Write(Message msg, List<Student> students)
        {
            msg.WriteScalar(students.Count);
            for (int i = 0; i < students.Count; ++i)
            {
                msg.Write(students[i].Name);
                msg.Write(students[i].ID);
                msg.Write(students[i].Kor);
                msg.Write(students[i].Eng);
                msg.Write(students[i].Mat);
            }
        }
    }
} 

C# marshalling is developed by inheriting and implementing Nettention.Proud.Marshaler.

This works with the keyword [marshaler (cs) = CsClient.MyMarshaler] declared in PIDL without having to do it yourself.

g_S2CStub.StudentList = (remote, rmiContext, students) =>
{
    lock(g_lock)
    {
        // You can use students which are transformed to List<Student>.
    foreach (var s in students)
        {
            Console.WriteLine(s.ToString());
        }
    }
    return true;
};