8. C および C++ での XML-RPC の使い方

C/C++ 用 XML-RPC のコピーを得るには、xmlrpc-c のウェブサイトを 見てください。

RPM 形式ですべてのものをダウンロードすることも、ソースから自分 で環境を構築することもできます。

8.1. C クライアント

次のプログラムコードを 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;
}

コンパイルするための入力を示します -

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

あなたのシステムの C コンパイラの名前が gcc ではないかもしれないので、実際の入力ではそ れを代える必要があるかもしれません。

8.2. C++ クライアント

次のプログラムコードを 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;
}

コンパイルするための入力を示します -

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

この作業のために、かなり最近の C++ コンパイラが必要となりま す。

8.3. 代替クラス (Proxy Class) での C++ クライアント

XML-RPC サーバがイントロスペクション API をサポートしているなら、自動的に そのサーバ用の C++ 代替クラスを生成できます。代替クラスを生成する ためには、次のコマンドを入力してその出力をファイルに保存してくださ い。

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

これは sample で始まるすべてのメソッド用 のラッパーが含まれている SampleProxy と名づけら れた代替クラスを生成します。あなたが望む方法でこのクラスを修正して もかまいません。

8.4. CGI ベースの C サーバ

次のプログラムコードを 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();
}

コンパイルするための入力を示します -

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

これが終了したら、sumAndDifference.cgi をウェブサーバの cgi-bin ディレクトリにコピー してください。