I have worked with client-server applications for a couple of years now, all of these applications use RPC as the layer of communication between the client and the server. I found it strange that no real article existed on this matter here on CodeProject, so I decided to write one of my own to spread my knowledge on this matter.

The matter is, on the other hand, a bit big so I will split it into several articles of different levels of difficulty. This first one is at beginner level.

IDL stands for Interface Definition Language and it's a language for defining interfaces (no kidding). Writing an IDL file is somewhat like writing a C header file with some additional keywords and constructs. IDL is an attributed programming language and thus it can describe parameters, functions and interfaces in more detail than C.

Remote Procedure Call (RPC) defines a powerful technology for creating distributed client/server programs. The RPC runtime libraries manage most of the details relating to network protocols and communication. This enables you to focus on the details of the application rather than the details of the network.

With RPC a client can connect to a server running on another platform. For example: In theory the server could be written for Linux and the client could be written for Win32. The reality is somewhat more complicated.

// File Example1.idl
[
// A unique identifier that distinguishes this// interface from other interfaces.uuid(00000001-EAF3-4A7A-A0F2-BCE4C30DA77E),
// This is version 1.0 of this interface.version(1.0),
// This interface will use an implicit binding// handle named hExample1Binding.implicit_handle(handle_t hExample1Binding)
]
interface Example1 // The interface is named Example1
{
// A function that takes a zero-terminated string.void Output(
[in, string] const char* szOutput);
}

Here you see the attribute programming used by IDL. The above example defines an interface with an universally unique identifier (uuid) and version (version) that is named Example1. The Example1 interface defines one function named Output that takes a const char* argument named szOutput as input (in) that is zero-terminated (string).

The implicit_handle attribute for the interface will be discussed later, leave it there for now.

In order to use the IDL in our application we need to run it through a compiler (midl.exe) that will translate the IDL to a client proxy and a server stub in C. The proxy/stub will later be compiled using your favorite compiler (cl.exe in my case).

First we need to compile the IDL file to get the client proxy, the server stub and the common header file. The proxy and the stub is compiled, as are the client and server implementation. We link the two applications and run them. If everything works, we can be really glad as we have done our first RPC client/server application.

If you get into trouble when debugging and the problem seem to be in a MIDL generated file, the real problem will most likely be in the client or in the server. I have sometime run into problems with pointers, but in a follow up article I will describe these things more thoroughly.

When using RPC, the binding handles can be implicit (as in the example in this article) or explicit. I always use explicit handles as I sometime are connected to multiple servers, and that does not work with the implicit handle. To use explicit handles, you'll have to change the IDL file, the server and the client:

// File Example1Explicit.idl
[
// A unique identifier that distinguishes this// interface from other interfaces.uuid(00000002-EAF3-4A7A-A0F2-BCE4C30DA77E),
// This is version 1.0 of this interface.version(1.0),
// This interface will use explicit binding handle.explicit_handle
]
interface Example1Explicit // The interface is named Example1Explicit
{
// A function that takes a binding handle and a zero-terminated string.void Output(
[in] handle_t hBinding,
[in, string] const char* szOutput);
}

In this example I used implicit_handle and explicit_handle directly in the IDL file, but that is a Microsoft extension. One usually need to use a separate Application Configuration File that contain these. The sample code in the zip file does use a separate ACF file, but I felt like, writing that in the article would only confuse you even more.

You should not fiddle with the generated files to make them compile, they are (should be) correct. Check the switches to midl.exe if you feel that they are incorrect. When compiling them you may on the other hand get a lot of warnings, but when lowering the warning level to 2, they are silent.

The example server will run until it is shut down by closing it somehow. That ain't the best way of doing it, another better way is to call the RpcMgmtStopServerListening function. But how would you call it? You could add another function in the interface (perhaps named Shutdown?) that will call RpcMgmtStopServerListening or you could create another thread in the server before calling RpcServerListen that will call RpcMgmtStopServerListening after a minute or so. More on this in another article.

Comments and Discussions

In trying to get RPC working using ncalrcp in my application for a very large tech company, I compiled these out of the box in VS 2015 and as 64 bit. They work perfectly as is using TCP/IP. Perhaps this is not news to some, but I did not see it mentioned anywhere in the comments.

But I did not yet succeed in getting NCALRPC working. Any help would be appreciated.

The generation of the ...s.c and ...c.c Files is working, but when I try to compile, it gives me this error-message.
I could of course change the unsigned char to char but I think this should not happend at all.
Are there any suggestions ?

The idl file was build as planned & 3files were generated. Then When i was trying to compile Example1Server.cpp I got the error named "Example1_v1_0_s_ifspec" undeclared identifier.So any solutions to this?

Some really cool stuff, I'd never seen RPC done at this level before. So it got me curious, and I created a small project to see what the MIDL compiler is outputting. Which then got me thinking...
It would really cool if you could just write a C++ class, and have a tool that parsed over the class and created the stub code for you, without having to bother with MIDL at all. The tool would have to be able to parse C++, there would obviously be limits on how fancy your class definitions got, but for most of the common constructs (i.e. support for prims like int, double, etc, and basic STL classes like vector and string) you make it handle this. You could use the tools that are part of Clang (see llvm.org and clang) for the parser (they have full C++ AST support), and then generate the same output that the MIDL compiler does. Add some support code in the form of a small utility framework to simplify things with the RPC calls, and you could have a cool little project that supports distributed C++ using RPC

I have followed your "Introduction to RPC - Part 2", I am able run the server in WP using mincore.lib.
It is perfectly working now

I have some doubts on RPC:

1) How to call client functions from the server (Using Callbacks)?
I have found small example for callbacks at http://support.microsoft.com/kb/96781, Its working fine.
But if I call CallbackProc( pszStr ); from some different thread, server is crashing.

2) I have to implement a GUI based client (instead of Win32 application) to take some input parameters and to display the results from the server, Can you please point me to some tutorial?

1) You can do callbacks only in threads of calls done by clients. You have 3 options:
1. call special purpose server method in specially started thread, server hangs this call, does callback any time it wants.
2. like in COM - each client is server. Each server is client. Server calls other server which is client to do callback. start RPC server on client side
3. polling. let client call some server methodsfrom time to time and take event queue stored on server to client side for interpretation.

2) start reading MSDN Learn to Program for Windows in C++. After it you will be pretty confident how to do you want.

ll last week i killing my head! Please update this article for MSVS 2010, because we (all noobs C++) need's help in RPC...
(on MSDN i read tutorial of RPC but their code has a some errors and i can't fix it... i love microsoft ;)
So please update this article and code for MSVS2010 - and Thank You very much!!!

We have created a C++ application (MFC)as a RPC server, built with VS6 and also the corresponding RPC client. Now we would like to keep the old server but replace the client with a C# application. I'm not familiar with C#.
Question: Is it possible to write an 'old fashioned' RPC client in C# and where can I get the documentation?