Skip to main content

skip to main content

developerWorks  >  SOA and Web services | XML  >

Enable C++ applications for Web service using XML-RPC

A step-by-step guide to exposing C++ methods as services

developerWorks
Document options

Document options requiring JavaScript are not displayed


Rate this page

Help us improve this content


Level: Intermediate

Karthik Subbian (ksubbian@in.ibm.com), Staff Software Engineer, IBM India
Ramakrishnan Kannan (rkrishnan@in.ibm.com), Staff Software Engineer, IBM India

20 Jun 2006

XML-RPC is a lightweight, simple and powerful messaging protocol that enables complex XML-based communication across disparate platforms. In this article you'll see how to build your own XML-RPC-based service for C++ programs.

Introduction

Today the growing popularity of the Internet and its inherent advantages have motivated developers and IT departments to migrate complex C/C++ business and scientific applications to a Web-based environment. Web services such as Simple Object Access Protocol (SOAP), Representational State Transfer (REST), and XML remote procedure protocol (XML-RPC) facilitate integration of such legacy applications to the World Wide Web, including XML-RPC as a mechanism to integrate existing C/C++ programs with other client-side technologies. This article will help you determine when to choose XML-RPC versus SOAP and REST. Also, a step-by-step guide and sample code snippets for C++ integration using an open source XML-RPC Library is provided.

Why XML-RPC?

The challenge of integrating C/C++ code has been solved in many ways. Some of the classical approaches of C/C++ code integration are through Common Object Request Broker Architecture (CORBA), distributed component object model (DCOM), remote method invocation (RMI) Internet Inter-ORB Protocol (IIOP) and Java™ native interface (JNI) interfaces.

Figure 1 illustrates three different applications developed in three different programming languages (Java, VC++, PL/1) integrating with existing C++ code using the classical approaches mentioned above.



Figure 1. Current scenario without XML-RPC
Current scenario without XML-RPC

As you can see, C++ code should expose the respective interfaces for each of the RMI/IIOP/JNI, CORBA and DCOM client-side integration technologies. This requires three-times the development effort and clearly makes the process of deploying and managing such complex interfaces much more difficult and cumbersome.

XML-RPC is a better choice in these situations because the development, deployment and management becomes easy.


About XML-RPC and REST

XML-RPC was conceived by Dave Winer of UserLand Software in 1998. Visit Dave Winer's blog about his initial idea for XML-RPC.

REST was first proposed by Roy Thomas Fielding as part of his Ph.D. dissertation from the University of California, Irvine.



Figure 2. With XML-RPC

Figure 2 illustrates invoking a C++ program through a remote procedure call using XML over HTTP. Alternate technologies like SOAP and REST, can serve the same purpose. Yet as you'll see in the next section, there are some key differences between these technologies.

Comparison of SOAP, XML-RPC and REST

Even through all three protocols support XML-RPC over HTTP there are differences among them with respect to C++. Table 1 offers a detailed comparison of the elements of these protocols.


Table 1. Comparison of SOAP, XML-RPC and REST
SOAPXML-RPCREST
DefinitionSOAP is a lightweight protocol for information exchange in a decentralized, distributed environment. It is an XML-based protocol that consists of three parts: an envelope, a set of encoding rules, and a convention for representing remote procedure calls and responses.This is a remote procedure call that uses HTTP as the transport and XML as the encoding. XML-RPC is designed to be as simple as possible, while allowing complex data structures to be transmitted, processed and returned.Representational State Transfer is intended to evoke an image of how a well-designed Web application behaves: a network of Web pages, where the user progresses through an application by selecting links, resulting in the next page being transferred to the user and rendered for their use.
GoalsSOAP extends XML-RPC by implementing user defined data types, the ability to specify the recipient, message specific processing control, and other features.A clean, extensible format that's very simple. An HTML coder tshould be able to look at a file containing an XML-RPC procedure call, understand what it's doing, and be able to modify it and have it work on the first or second try. An easy-to-implement protocol that could quickly be adapted to run in other environments or on other operating systems.REST was created to provide a design pattern for how the Web should work, and to serve as the guiding framework for the Web standards and designing Web services.
Data types supportedInteger, Boolean, ASCII String, double precision signed floating point number, date-time, structs, arrays, array of bytes, enumeration, User-defined data types, polymorphic accessorsInteger, boolean, ASCII string, double-precision signed floating point number, date-time, structs, arrays.Implementation specific. In general supported types are Integer, boolean, ASCII string, double-precision signed floating point number, date-time, set, list, properties.
SimplicitySlightly complex compared to XML-RPCEasy to understand and developImplementation-specific
StabilityAccepted standard under W3CNot a standardArchitecture reference. Standard not needed
InteroperabilityCannot interoperate with REST/XML-RPCCannot interoperate with REST/SOAPCannot interoperate with SOAP/XML-RPC
ToolingMany major companies including IBM and Microsoft started supporting SOAP in their tools.Tooling is still evolving.Not many tooling support is available.
CustomizabilityHighly customizable, data-types and protocol independentLightweight, can work only on HTTP, limited data type supportWorks only on HTTP
LibraryMany open source libraries are available.Many open source libraries are available. The following sections offer descriptionsNot many implementation library available

Table 2. Various XML-RPC implementations for C++
Library and package nameDescription
PDELPacket Design Embedded Library is a C library containing XML-RPC implementation of client and server through http_xml_send_xmlrpc and http_servlet_xmlrpc methods. These functions help you to send your custom xml data over the http transport protocol. This package also has many other features other than XML-RPC.
XMLRPC++This is a C++ implementation of the XML-RPC standard. It comes with a simple server and a client. Using object-oriented techniques, we can inherit these server and client classes and implement our own XML-RPC server exposing our business functions as services. In this article, we have used this library for sample implementation and examples.
XMLRPC-CThis is a C implementation which can be used by both C and C++ applications for exposing there methods as services. This package includes an abyss web server. For exposing C++ methods we could write C style wrapper to the required C++ method, and expose this method using this library.

Install XML-RPC++ library

The first step towards enabling your C++ program for XML-RPC is to download and install an XML-RPC library implementation. Various implementations are available for C++ programs. A link to more implementations can be found in the Resources section.

Our sample programs use the XMPLRPC++ implementation. The details of downloading and installing this to Linux, AIX, 32-Bit windows platforms, and other familiar platforms, can be found in the Resources section. Our sample implementation is on the Red Hat 9 platform, using XML-RPC++ 0.7 library.

A sample C++ application

The sample application here is a simple addition operation on two integers, using a user-defined class called " operations " . Listing 1 shows the code snippet for the operations class.



Did you know?

You can use use Eclipse as IDE to develop C/CPP application. Visit Eclipse CDT for more information.


Listing 1. Operations
        
class operations {
public:
   int add();
   operations(int i, int j);

private:
   int op1;//Operand 1
   int op2;//Operand 2
};


The constructor for this class takes two integer parameters and sets them to op1 and op2 private variables respectively. The add method for this class is shown in Listing 2. This is the method, we are interested to expose as a XML-RPC service.


Listing 2. Operations.cpp
        
int operations::add()
{
        std::cout << "Sum of "<<op1<<" + "<<op2<<" = "<<op1+op2<<std::endl;
        return(op1 + op2);
}



Back to top


Components of XML-RPC library

In this section we use a a class diagram to explain various components of the XML-RPC library and how it interfaces with our operations class for the server side.



Figure 3. Class diagram for XML-RPC library and sample application
Class diagram for XML-RPC library and sample application

Each class is explained in detail in Table 3.


Table 3. Class details
Class namePurpose
Operations Add method to be exposed is implemented in this class
AddWrapper class which will call the operations add method(). This class also inherits from myXmlRpcServerMethod
myXmlRpcServerMethodThis class inherits from XML-RPC Library XmlRpcServerMethod class. The execute of this is overridden in Add class, through inheritance.
xmlRpcServermethodEvery method that needs to be registered to the server has to inherit from this class through myXmlRpcServerMethod class and implement its execute method. This execute method will be the wrapper for the actual service exposed. Whenever an XML-RPC call is received by the server, it immediately triggers the execute method of this wrapper class. In our case, Add will be the wrapper class and its execute method will be called when we invoke "Add" service from client side.
myXmlRpcServerThis class has two important private variables
  1. pm_serverMethods: List of pointers to myXmlRpcServerMethods which are registered in server.
  2. pm_xmlRpcServer: To set the server IP, Port and other properties.

Three important methods
  1. Class constructor: initializes server object with ip/port details and binds it.
  2. pm_registerMethods: create a pointer object to Add class and push it to the list, pm_serverMethods.
  3. run: This is a wrapper for work method in xmlRpcServer class
xmlRpcServerThis class is the XML-RPC server class which creates a server object. This class has following two important methods
  1. bindAndListen(port): bind and listen to the specific port mentioned
  2. work(...): start the server

Listing 3 shows the code for each .cpp file for each class in the above table. Since xmlRpcServer and xmlRpcServerMethod are implemented in the XML-RPC library, we concentrate on the remaining four classes.



Listing 3. myXmlRpcServer.cpp
        
#include "myXmlRpcServer.h"

using namespace XmlRpc;
using namespace std;

myXmlRpcServer::myXmlRpcServer()
{
//call register methods
pm_registerMethods();

//set port bind and listen
int port = 8085;
pm_xmlRpcServer.bindAndListen(port);
std::cout<<"XmlRpcSever running in port "<<port<<std::endl;
}

void
myXmlRpcServer::pm_registerMethods()
{
        Add* a=new Add(&pm_xmlRpcServer);
        myXmlRpcServerMethod *p=a;
        pm_serverMethods.push_back(p); 
}

void
myXmlRpcServer::run()
{
        pm_xmlRpcServer.work(-1);
}


Listing 4. myXmlRpcServer.h
        
#include <iostream>
#include "myXmlRpcServerMethods.h"
#include "XmlRpc.h"

class myXmlRpcServer {
public:
        myXmlRpcServer();
        void run();
private: 
        void pm_registerMethods();
        XmlRpc::XmlRpcServer pm_xmlRpcServer;
        std::list< myXmlRpcServerMethod* > pm_serverMethods;
};

Listing 5 and Listing 6 show code for classes that are used for registering the methods to the XmlRpc Server that comes as a part of the XML-RPC library.



Listing 5. myXmlRpcServerMethods.cpp
        
#include <iostream>
#include "myXmlRpcServer.h"
#include "operations.h"

using namespace std;

Add::Add(XmlRpcServer* s) : myXmlRpcServerMethod("Add", s) {};

Void Add::execute(XmlRpcValue & params, XmlRpcValue& result)
{
 operations a(10,12);
 try 
    {
      cout << "Inside Add::execute method\n";
      result = a.add();
    }
  catch(std::exception & stde)
    {
      throw XmlRpcException(stde.what());
    }
}



Listing 6. myXmlRpcServerMethods.h
        
class myXmlRpcServerMethod : public XmlRpcServerMethod
{
public:
  myXmlRpcServerMethod
   (const char *name, XmlRpcServer * server):XmlRpcServerMethod(name, server) {}
   virtual void execute(XmlRpcValue & params, XmlRpcValue& result) {assert(0);}
};

class Add:public myXmlRpcServerMethod
{
public:
   Add(XmlRpcServer* s); 
   virtual void execute(XmlRpcValue & params, XmlRpcValue& result);
};

Server driver

The entry point for the server side will be through the server driver program. It is the place to instantiate myXmlRpcServer object and call the run() method, which will eventually start the server.


Listing 7. myServerDriver.cpp
        
#include <iostream>
#include "myXmlRpcServer.h"

int main(int argc, char* argv[])
{
        myXmlRpcServer GeeBoomBaa;
        std::cout<<"About to run the server\n";
        GeeBoomBaa.run();
        return 0;
}



Back to top


Starting the server

In order to compile the code, remember to include the (XML_RPC_INSTALL_DIR)/src and (XML_RPC_INSTALL_DIR)/include directory. For linking purposes, include the libXmlRpc.a library. Once the code is successfully compiled and linked, you will have an executable, which is the XML-RPC Server. In our sample implementation, the server will run on localhost and listen to port 8085. This is hard-coded in myXmlRpcServer.cpp file. Instead, it could read a configuration file or you could pass this as a parameter from the command prompt. Start the server by running the a.out program obtained after successful compilation and linking.



Back to top


Sample client

Sample client should instantiate an object from XmlRpcClient class provided in the XML-RPC library. The "execute(...)" method of this class, actually takes three parameters:

  1. method name as const char*
  2. port number as const int
  3. An optional uri string to be sent as Uri in the http get header
Listing 8 shows a sample client, which will execute the "add(...)" method and print the result on the client side.


Listing 8. sampleClient.cpp
        
#include <iostream>
#include "XmlRpc.h"
using namespace XmlRpc;

int main(int argc, char* argv[])
{
        const char *server = "localhost";
        const int port = 8085;
        const char *uri = NULL;
        XmlRpcValue args, res;

        XmlRpcClient c( server, port, uri);
        c.execute("Add", args, res);
        std::cout<<"result is "<<res<<std::endl;
}



Back to top


Conclusion

XML-RPC is a lightweight, simple and powerful messaging protocol that enables complex XML-based communication across disparate platforms. The inherent simplicity of this standard is very powerful and useful for integrating legacy applications with an enterprise. The open source nature of various XML-RPC implementations has promoted this technology to gain more popularity among Enterprise Application Integrations. With the advent of more and more sophisticated tools for XML-RPC, we expect this technology to become a "defacto" standard for intra-enterprise integration.



Resources

Learn

Get products and technologies

Discuss


About the authors

Karthik Subbian

Karthik Subbian is currently building optimization products for manufacturing enterprises in IBM India Software Laboratory, Bangalore. He also has experience helping clients imanage their applications and migrate them to IBM platforms. His areas of interests in the software arena include Grid computing, XML, Web services and SOA. He has co-authored IBM Redbooks on Grid computing technology. He is an IBM Certified XML Solution Developer and Sun Certified Java Programmer.


Ramakrishnan Kannan

Ramakrishnan Kannan works on host integration in IBM India Software Laboratory in Bangalore. He has been a developer for IBM personal communications and communication servers products. In addition to his development work, he works with customers in IBM Asia-Pacific region for Web service enablement of Host Applications. He has conducted webservices awareness session to business partners such as Infosys for Developerworks. He is an IBM Certified XML Solution Developer and Sun Certified Java Professional. His interests are host integration, distributed computing, SOA, and networking.




Rate this page


Please take a moment to complete this form to help us better serve you.



YesNoDon't know
 


 


12345
Not
useful
Extremely
useful
 


Back to top