Using XML-RPC with C and C++

XML-RPC HOWTO
Prev |  | Next

# 8. Using XML-RPC with C and C++

To get a copy of XML-RPC for C/C++, see the xmlrpc-c website.

You can either download everything in RPM format, or you can build it from source.

## 8.1. A C Client

Save the following code in a file called `getSumAndDifference.c`:

    #include <stdio.h>
    #include <xmlrpc.h>
    #include <xmlrpc_client.h>

    #define NAME       "XML-RPC getSumAndDifference C Client"
    #define VERSION    "0.1"
    #define SERVER_URL "http://xmlrpc-c.sourceforge.net/api/sample.php"

    void die_if_fault_occurred (xmlrpc_env *env)
    {
        /* Check our error-handling environment for an XML-RPC fault. */
        if (env->fault_occurred) {
            fprintf(stderr, "XML-RPC Fault: %s (%d)\n",
                    env->fault_string, env->fault_code);
            exit(1);
        }
    }

    int main (int argc, char** argv)
    {
        xmlrpc_env env;
        xmlrpc_value *result;
        xmlrpc_int32 sum, difference;

        /* Start up our XML-RPC client library. */
        xmlrpc_client_init(XMLRPC_CLIENT_NO_FLAGS, NAME, VERSION);
        xmlrpc_env_init(&env);

        /* Call our XML-RPC server. */
        result = xmlrpc_client_call(&env, SERVER_URL,
                                    "sample.sumAndDifference", "(ii)",
                                    (xmlrpc_int32) 5,
                                    (xmlrpc_int32) 3);
        die_if_fault_occurred(&env);

        /* Parse our result value. */
        xmlrpc_parse_value(&env, result, "{s:i,s:i,*}",
                           "sum", &sum,
                           "difference", &difference);
        die_if_fault_occurred(&env);

        /* Print out our sum and difference. */
        printf("Sum: %d, Difference: %d\n", (int) sum, (int) difference);

        /* Dispose of our result value. */
        xmlrpc_DECREF(result);

        /* Shutdown our XML-RPC client library. */
        xmlrpc_env_clean(&env);
        xmlrpc_client_cleanup();

        return 0;
    }

To compile it, you can type:

    bash$ CLIENT_CFLAGS=`xmlrpc-c-config libwww-client --cflags`
    bash$ CLIENT_LIBS=`xmlrpc-c-config libwww-client --libs`
    bash$ gcc $CLIENT_CFLAGS -o getSumAndDifference getSumAndDifference.c $CLIENT_LIBS

You may need to replace gcc with the name of your system's C compiler.

## 8.2. A C++ Client

Save the following code in a file called `getSumAndDifference2.cc`:

    #include <iostream.h>
    #include <XmlRpcCpp.h>

    #define NAME       "XML-RPC getSumAndDifference C++ Client"
    #define VERSION    "0.1"
    #define SERVER_URL "http://xmlrpc-c.sourceforge.net/api/sample.php"

    static void get_sum_and_difference () {

        // Build our parameter array.
        XmlRpcValue param_array = XmlRpcValue::makeArray();
        param_array.arrayAppendItem(XmlRpcValue::makeInt(5));
        param_array.arrayAppendItem(XmlRpcValue::makeInt(3));

        // Create an object to resprent the server, and make our call.
        XmlRpcClient server (SERVER_URL);
        XmlRpcValue result = server.call("sample.sumAndDifference", param_array);

        // Extract the sum and difference from our struct.
        XmlRpcValue::int32 sum = result.structGetValue("sum").getInt();
        XmlRpcValue::int32 diff = result.structGetValue("difference").getInt();

        cout << "Sum: " << sum << ", Difference: " << diff << endl;
    }

    int main (int argc, char **argv) {

        // Start up our client library.
        XmlRpcClient::Initialize(NAME, VERSION);

        // Call our client routine, and watch out for faults.
        try {
            get_sum_and_difference();
        } catch (XmlRpcFault& fault) {
            cerr << argv[0] << ": XML-RPC fault #" << fault.getFaultCode()
                 << ": " << fault.getFaultString() << endl;
            XmlRpcClient::Terminate();
            exit(1);
        }

        // Shut down our client library.
        XmlRpcClient::Terminate();
        return 0;
    }

To compile it, you can type:

    bash$ CLIENT_CFLAGS=`xmlrpc-c-config c++ libwww-client --cflags`
    bash$ CLIENT_LIBS=`xmlrpc-c-config c++ libwww-client --libs`
    bash$ c++ $CLIENT_CFLAGS -o getSumAndDifference2 getSumAndDifference2.cc $CLIENT_LIBS

You'll need a reasonably modern C++ compiler for this to work.

## 8.3. A C++ Client with Proxy Classes

If your XML-RPC server supports the Introspection API, you can automatically generate C++ proxy classes for it. To generate a proxy class, type the following command and save the output to a file:

    bash$ xml-rpc-api2cpp \
    > http://xmlrpc-c.sourceforge.net/api/sample.php sample SampleProxy

This will generate a proxy class named `SampleProxy` containing wrappers for all the methods beginning with `sample`. You can edit this class in any fashion you'd like.

## 8.4. A CGI-Based C Server

Save the following code in a file called `sumAndDifference.c`:

    #include <xmlrpc.h>
    #include <xmlrpc_cgi.h>

    xmlrpc_value *
    sumAndDifference (xmlrpc_env *env, xmlrpc_value *param_array, void *user_data)
    {
        xmlrpc_int32 x, y;

        /* Parse our argument array. */
        xmlrpc_parse_value(env, param_array, "(ii)", &x, &y);
        if (env->fault_occurred)
            return NULL;

        /* Return our result. */
        return xmlrpc_build_value(env, "{s:i,s:i}",
                                  "sum", x + y,
                                  "difference", x - y);
    }

    int main (int argc, char **argv)
    {
        /* Set up our CGI library. */
        xmlrpc_cgi_init(XMLRPC_CGI_NO_FLAGS);

        /* Install our only method (with a method signature and a help string). */
        xmlrpc_cgi_add_method_w_doc("sample.sumAndDifference",
                                    &sumAndDifference, NULL,
                                    "S:ii", "Add and subtract two integers.");

        /* Call the appropriate method. */
        xmlrpc_cgi_process_call();

        /* Clean up our CGI library. */
        xmlrpc_cgi_cleanup();
    }

To compile it, you can type:

    bash$ CGI_CFLAGS=`xmlrpc-c-config cgi-server --cflags`
    bash$ CGI_LIBS=`xmlrpc-c-config cgi-server --libs`
    bash$ gcc $CGI_CFLAGS -o sumAndDifference.cgi sumAndDifference.c $CGI_LIBS

Once this is done, copy `sumAndDifference.cgi` into your webserver's `cgi-bin` directory.

Prev | Home | Next
Using XML-RPC with Python |  | Using XML-RPC with Java