|
The C++/CLI .NET Remoting Program Example
Creating the C++ Remoting Demo Class Library (DLL)
Create new C++ class library and you can use the project and solution names as shown in the following screenshot.
Add/edit the code skeleton of the DemoCP.h as given in the following paragraph. |
// DemoCP.h
#pragma once
using namespace System;
namespace DemoCP {
/// <summary> /// DemoClass is a very simple class that demonstrates Marshal by Value and /// Marshal by Reference in .Net remoting. /// </summary> /// [Serializable] // for Marshaling by value public ref class InformationBucket { public: int Value; public: String^ Message; };
// for Marshaling by reference public ref class DemoClass : MarshalByRefObject { private: static int Value = 0; private: static String^ Message = "";
// method for setting a value public: void SetValue(int InputValue) { Value = InputValue; Console::WriteLine("Demo class\'s SetValue(): Setting Value to {0}", InputValue); }
// method for displaying a message public: void SetMessage(String^ InputMessage) { Message = InputMessage; Console::WriteLine("Demo class\'s SetMessage(): Setting Message to {0}", InputMessage); }
public: InformationBucket^ GetCurrentInformation() { InformationBucket^ Bucket = gcnew InformationBucket();
Bucket->Message = Message; Bucket->Value = Value;
return Bucket; } }; } |
Build the project and make sure there is no error.
The DLL file should be generated and ready for use.
Create new C++ console application. You can use the project and solution names as shown in the following screenshot. This server program should be deployed on the server side in the real deployment.
Add/edit the code as given below. The communication detail such as protocol, port number and the DLL to be searched and loaded is stored in the app.config file which will be created later. Take note that in C++ .NET, the app.config file name cannot be changed.
// ServerCP.cpp : main project file.
#include "stdafx.h"
using namespace System; using namespace System::Runtime::Remoting;
/// <summary> /// Demonstrates how to develop a server to sponsor a remote object /// </summary> [STAThread] int main(array<System::String ^> ^args) { // check the created config file path and change accordingly RemotingConfiguration::Configure("..\\ServerCP\\app.config", false); Console::WriteLine("Server: Reading the config file..."); Console::WriteLine("Server: I'm ready, press return to exit the server dude!"); Console::ReadLine();
return 0; } |
Add new item, the config file.
Select the Configuration file (aap.config) template and the file name cannot be changed. Click the Add button.
Add the following schema settings inside the <configuration>…</configuration> tag. The remoting schema details can be found in Remoting Settings Schema.
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.runtime.remoting> <application> <service> <activated type="DemoCP.DemoClass, DemoCP" /> </service> <channels> <channel ref="tcp" port="3131" /> </channels> </application> </system.runtime.remoting> </configuration> |
Next, as set in the app.config file, we need to store the DemoCP DLL binary in the server’s \Debug project folder so that the server program can find it. Copy all file under the DemoCP\Debug folder. Take note that the DemoCP DLL is a Debug version.
Paste the copied files into the ServerCP\Debug folder.
Build the project and make sure there is no error.
Then, we are ready to run this server program. Run the project without debugging.
Unblock the firewall if any.
The following screenshot shows the server program is ready for the client communication with remoting call.
Create a new C++ console application. You can use the solution and project name as shown in the following screenshot.
Next, add a reference to DemoCP DLL. Invoke the Reference page.
|
|
From the Framework and References subfolder of the ClientCP Property Pages, click Add New Reference button.
From the Browse page of the Add Reference, find and select the DemoCP.dll which is under the project’s Debug folder. Click OK to add the reference.
The reference should be visible under the References window of the property page.
In the background, the DLL and related file will be automatically copied to the project folder. When we update the DemoCP project, the copied DLL also will be automatically updated during the ClientCP rebuilding process.
Add/edit the ClientCP code as given below.
// ClientCP.cpp : main project file.
#include "stdafx.h"
using namespace System; using namespace System::Runtime::Remoting; using namespace DemoCP;
/// <summary> /// This is a simple .Net remoting application that demonstrates /// how to configure .Net remoting via configuration files and also shows /// how to perform both marshal by reference and marshal by value. /// </summary> [STAThread] int main(array<System::String ^> ^args) { // Test if input arguments were supplied // args[0] = 1st argument, args[1] = 2nd argument, ... if (args->Length == 1) { Console::WriteLine("Please enter a numeric value followed by a message!"); Console::WriteLine("Example: <binary> 123 \"Remoting: Some string from client sent to Demo class \n then displayed on Server\""); Environment::Exit(1); }
try { Console::WriteLine("Client: Reading the config file..."); // check the created app.config file in your project and change the path accordingly RemotingConfiguration::Configure("..\\ClientCP\\app.config", false);
Console::WriteLine("Client: Instantiating the DemoClass object..."); DemoClass^ MyDemo = gcnew DemoClass();
// The following call demonstrates marshal by reference // because we set a numeric value on the server from the client. Console::WriteLine("Client: DemoClass object - Setting the value..."); MyDemo->SetValue(Int32::Parse(args[0]));
// The following call also demonstrates marshal by reference // because we set a string value on the server from the client. Console::WriteLine("Client: DemoClass object - Setting the message..."); MyDemo->SetMessage(args[1]);
// The following call also demonstrates marshal by value because // we retrieve a serializable object named InformationBucket // from the server and get a copy to access on the client. Console::WriteLine("Client: DemoClass object - getting the current info..."); InformationBucket^ IB = MyDemo->GetCurrentInformation();
Console::WriteLine(); Console::WriteLine("Client: The message is: " + IB->Message); Console::WriteLine("Client: The value is: " + IB->Value.ToString()); } catch (Exception^ err) { Console::WriteLine("Error lor: {0}", err); } return 0; } |
Build the project.
The referred DLL also updated which can be seen in the Output window.
Next, add the config file for the protocol and port number. Invoke the Add > New Item menu.
Select the Configuration file (app.config) template. In C++ the file name cannot be changed.
Add the following schema settings inside the <configuration>…</configuration> tag. The detail of remoting configuration schemas can be found in Remoting Settings Schema.
<system.runtime.remoting> <application name="DemoClient">
<client url="tcp://localhost:3131"> <activated type="DemoCP.DemoClass, DemoCP" /> </client>
</application> </system.runtime.remoting> |
Run the project without debugging.
The following shows the client output sample. We need to run this program from the command prompt while the server program is running.
Firstly, open the server program in Visual Studio and run it without debugging. The output for the server program is shown below. Leave the server program in running mode.
Then, run the client program from the command prompt with an integer followed by a message as the arguments. The following screenshot shows the sample output with the client program run several times.
And the previous server output is shown below indicating a communication has taken place with remoting feature.