クライアントとサーバとが相互通信するデータ処理システムであって、前記クライアントは、ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得するユーザ関数シンボル名取得部と、テンプレート関数として定義され、かつ、その内部で前記ユーザ関数を実行するラッパ関数へのポインタを、前記ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得するラッパ関数ポインタ取得部と、前記ラッパ関数へのポインタを用いて、前記ラッパ関数のラッパ関数シンボル名を取得するラッパ関数シンボル名取得部と、を有し、前記サーバは、前記ユーザ関数シンボル名、前記ユーザ関数の引数に対応するデータ、前記ラッパ関数シンボル名、及び、前記ユーザプログラム及び前記ラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムを前記クライアントから取得する通信部と、前記通信部により取得された前記ラッパ関数シンボル名を用いて前記ラッパ関数へのポインタを取得するラッパ関数ポインタ取得部と、前記通信部により取得された前記ユーザ関数シンボル名及び前記ユーザ関数の引数に対応するデータを引数として、前記ラッパ関数へのポインタで特定される、前記共有ライブラリ化ユーザプログラム内の前記ラッパ関数を実行するラッパ関数実行部と、を有するデータ処理システム。前記通信部は、前記ユーザ関数の引数に対応するデータとして、シリアライズされた引数データを前記クライアントから取得し、前記ラッパ関数実行部は、前記ラッパ関数の実行に伴い実行されるユーザ関数ポインタ取得部及びユーザ関数実行部を含み、前記ユーザ関数ポインタ取得部は、前記通信部により取得された共有ライブラリ化ユーザプログラム及び前記ユーザ関数シンボル名に基づいて、呼び出すべきユーザ関数へのユーザ関数ポインタを取得し、前記ユーザ関数実行部は、前記通信部で取得されたシリアライズされた引数データから前記ユーザ関数の引数を復元し、前記ユーザ関数ポインタと、当該復元された引数とを用いて、前記ユーザ関数を実行する、請求項1に記載のデータ処理システム。ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得するユーザ関数シンボル名取得部と、テンプレート関数として定義され、かつ、その内部で前記ユーザ関数を実行するラッパ関数へのポインタを、前記ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得するラッパ関数ポインタ取得部と、前記ラッパ関数へのポインタを用いて、前記ラッパ関数のラッパ関数シンボル名を取得するラッパ関数シンボル名取得部と、前記ユーザ関数シンボル名、前記ユーザ関数の引数に対応するデータ、前記ラッパ関数シンボル名、及び、前記ユーザプログラム及び前記ラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムを他のコンピュータ装置へ送信する通信部と、を有するコンピュータ装置。ユーザプログラム、及び、テンプレート関数として定義され、かつ、その内部で当該ユーザプログラムに含まれるユーザ関数を実行するラッパ関数が、共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラム、ユーザ関数シンボル名、ユーザ関数の引数に対応するデータ、及び、ラッパ関数シンボル名を他のコンピュータ装置から取得する通信部と、前記通信部により取得された前記ラッパ関数シンボル名を用いて前記ラッパ関数へのポインタを取得するラッパ関数ポインタ取得部と、前記通信部により取得された前記ユーザ関数シンボル名及び前記ユーザ関数の引数に対応するデータを引数として、前記ラッパ関数へのポインタで特定される、前記共有ライブラリ化ユーザプログラム内の前記ラッパ関数を実行するラッパ関数実行部と、を有するコンピュータ装置。前記通信部は、前記ユーザ関数の引数に対応するデータとして、シリアライズされた引数データを前記他のコンピュータ装置から取得し、前記ラッパ関数実行部は、前記ラッパ関数が実行されると起動されるユーザ関数ポインタ取得部及びユーザ関数実行部を含み、前記ユーザ関数ポインタ取得部は、前記通信部により取得された共有ライブラリ化ユーザプログラム及び前記ユーザ関数シンボル名に基づいて、呼び出すべきユーザ関数へのユーザ関数ポインタを取得し、前記ユーザ関数実行部は、前記通信部で取得されたシリアライズされた引数データから前記ユーザ関数の引数を復元し、前記ユーザ関数ポインタと、当該復元された引数とを用いて、前記ユーザ関数を実行する、請求項4に記載のコンピュータ装置。相互通信するクライアントとサーバとにより実行されるプログラムであって、前記クライアントに、ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得するユーザ関数シンボル名取得部と、テンプレート関数として定義され、かつ、その内部で前記ユーザ関数を実行するラッパ関数へのポインタを、前記ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得するラッパ関数ポインタ取得部と、前記ラッパ関数へのポインタを用いて、前記ラッパ関数のラッパ関数シンボル名を取得するラッパ関数シンボル名取得部と、を実現させ、前記サーバに、前記ユーザ関数シンボル名、前記ユーザ関数の引数に対応するデータ、前記ラッパ関数シンボル名、及び、前記ユーザプログラム及び前記ラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムを前記クライアントから取得する通信部と、前記通信部により取得された前記ラッパ関数シンボル名を用いて前記ラッパ関数へのポインタを取得するラッパ関数ポインタ取得部と、前記通信部により取得された前記ユーザ関数シンボル名及び前記ユーザ関数の引数に対応するデータを引数として、前記ラッパ関数へのポインタで特定される、前記共有ライブラリ化ユーザプログラム内の前記ラッパ関数を実行するラッパ関数実行部と、を実現させるプログラム。前記サーバで実現される前記通信部は、前記ユーザ関数の引数に対応するデータとして、シリアライズされた引数データを前記クライアントから取得し、前記サーバで実現される前記ラッパ関数実行部は、前記ラッパ関数が実行されると起動されるユーザ関数ポインタ取得部及びユーザ関数実行部を含み、前記ユーザ関数ポインタ取得部は、前記通信部により取得された共有ライブラリ化ユーザプログラム及び前記ユーザ関数シンボル名に基づいて、呼び出すべきユーザ関数へのユーザ関数ポインタを取得し、前記ユーザ関数実行部は、前記通信部で取得されたシリアライズされた引数データから前記ユーザ関数の引数を復元し、前記ユーザ関数ポインタと、当該復元された引数とを用いて、前記ユーザ関数を実行する、請求項6に記載のプログラム。相互通信するクライアントとサーバとにより実行されるデータ処理方法であって、前記クライアントが、ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得し、テンプレート関数として定義され、かつ、その内部で前記ユーザ関数を実行するラッパ関数へのポインタを、前記ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得し、前記ラッパ関数へのポインタを用いて、前記ラッパ関数のラッパ関数シンボル名を取得し、前記サーバが、前記ユーザ関数シンボル名、前記ユーザ関数の引数に対応するデータ、前記ラッパ関数シンボル名、及び、前記ユーザプログラム及び前記ラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムを前記クライアントから取得し、前記ラッパ関数シンボル名を用いて前記ラッパ関数へのポインタを取得し、前記ユーザ関数シンボル名及び前記ユーザ関数の引数に対応するデータを引数として、前記ラッパ関数へのポインタで特定される、前記共有ライブラリ化ユーザプログラム内の前記ラッパ関数を実行する、データ処理方法。前記ユーザ関数の引数に対応するデータは、シリアライズされた引数データであり、前記ラッパ関数の実行は、前記共有ライブラリ化ユーザプログラム及び前記ユーザ関数シンボル名に基づいて、呼び出すべきユーザ関数へのユーザ関数ポインタを取得すること、前記シリアライズされた引数データから前記ユーザ関数の引数を復元すること、前記ユーザ関数ポインタと、前記復元された引数とを用いて、前記ユーザ関数を実行することを、含む、請求項8に記載のデータ処理方法。参考例まず、本発明の参考例を図1および図2を参照して以下に説明する。図1に示されるように、本発明の参考例のデータ処理システムは、クライアント100とサーバ110とから構成される。クライアント100は、ユーザプログラム101、クライアントライブラリ103等を有する。ユーザプログラム101は共有ライブラリ化ユーザプログラム102を持つ。クライアントライブラリ103はユーザ関数シンボル名取得部104と通信部105とを有する。サーバ110は、サーバライブラリ111を有する。サーバライブラリ111は、通信部112、ユーザ関数ポインタ取得部113、ユーザ関数実行部115等を有する。サーバライブラリ111は、クライアント100から取得した共有ライブラリ化ユーザプログラム114をユーザ関数ポインタ取得部113からアクセスできる形で保持する。これらは概略次のように動作する。ユーザは、ユーザプログラム101を記述し、ユーザプログラム101とクライアントライブラリ103とをリンクさせる。クライアントライブラリ103及びサーバライブラリ111は、ユーザプログラム101によらず同じものが利用される。また、ユーザプログラム101をコンパイルすると、コンパイルされたユーザプログラム101は共有ライブラリとしても保存される。これは共有ライブラリ化ユーザプログラム102と表記される。ユーザプログラム101内では、まず、初期化が行われる。この中で、ユーザプログラム101は、共有ライブラリ化ユーザプログラム102をクライアントライブラリ103に渡し、その共有ライブラリ化ユーザプログラム102を通信部105を経由してサーバ110に送信する。サーバ110は、通信部112でこれを受信し、受信された共有ライブラリ化ユーザプログラムをサーバライブラリ111の内部に共有ライブラリ化ユーザプログラム114として保持する。初期化後、ユーザプログラム101は、サーバ110側で関数を呼び出す指示を行う。この関数を以後ユーザ関数と呼ぶ。ここで、ユーザプログラム101は、呼び出したいユーザ関数へのポインタと、その引数をクライアントライブラリ103に渡す。クライアントライブラリ103では、ユーザ関数シンボル名取得部104が、そのユーザ関数ポインタが指すオブジェクトのユーザ関数シンボル名を取得する。この取得処理は、例えば、Linuxの場合、dladdr関数を用いることで実現可能である。クライアントライブラリ103は、このシンボル名と与えられた引数とを通信部105を経由してサーバ110に送信する。サーバ110は、通信部112で、それらを受信する。サーバ110は、ユーザ関数のシンボル名をユーザ関数ポインタ取得部113に渡す。ユーザ関数ポインタ取得部113は、初期化時に取得した共有ライブラリ化ユーザプログラム114、およびユーザ関数シンボル名から、呼び出すべきユーザ関数へのポインタを取得する。この取得処理は、例えば、Linuxの場合、dlopen関数で共有ライブラリをオープンし、そこで得られたハンドルと、ユーザ関数シンボル名を引数にしてdlsym関数を呼び出すことで実現され得る。ユーザ関数実行部115は、このユーザ関数ポインタと、引数を用いて、ユーザ関数を実行する。ユーザ関数実行部115は、その実行結果の返り値を通信部112を経由してクライアント100に送信する。クライアントライブラリ103は、通信部105で関数の実行結果である返り値を受信する。クライアントライブラリ103は、受信された返り値をユーザプログラム101に返す。このようにすることで、クライアント100からの指示により、指定された関数をサーバ110側で実行することが可能となる。次に、図1および図2を参照して本参考例の全体の動作について詳細に説明する。まず、ユーザプログラム101は、共有ライブラリ化ユーザプログラム102を指定して初期化を実行する図2のステップ201。これにより、クライアントライブラリ103が、共有ライブラリ化ユーザプログラム102をサーバ110に送信するステップ211。サーバライブラリ111は、これを受信しステップ221、受信された共有ライブラリ化ユーザプログラムをサーバライブラリ111に登録するステップ222。次に、ユーザプログラム101が、サーバ110でユーザ関数を実行するために、ユーザ関数ポインタと引数をクライアントライブラリ103に渡すステップ202。クライアントライブラリ103はこれを受け取りステップ212、ユーザ関数ポインタを用いてユーザ関数シンボル名を取得するステップ213。クライアントライブラリ103は、得られたユーザ関数シンボル名と引数をサーバ110に送信するステップ214。サーバライブラリ111は、ユーザ関数シンボル名と引数を受信しステップ223、ユーザ関数シンボル名と登録しておいた共有ライブラリ化ユーザプログラム114からユーザ関数ポインタを取得するステップ224。サーバライブラリ111は、このユーザ関数ポインタと引数を用いてユーザ関数を実行しステップ225、その結果の返り値をクライアントライブラリ103に送信するステップ226。クライアントライブラリ103はこれを受信しステップ215、その受信された返り値をユーザプログラム101に返すステップ203。ステップ202から203を繰り返すことで、ユーザプログラム101は複数回、サーバ110側で関数を実行することが可能である。第一の実施形態次に、本発明の第一の実施形態について図3および図4を参照して詳細に説明する。ところで、上述の参考例においては、サーバ110側で実行される関数の引数の数や型、返り値の型が指定できず、固定になっていた。その理由は、関数ポインタをユーザ関数ポインタ取得部113で取得するだけでは、その関数の引数の数や型の情報は得られないからである。第一の実施形態はこの点を解決している。図3に示されるように、第一の実施形態におけるデータ処理システムは、クライアント300とサーバ310から構成される。クライアント300とサーバ310とは相互に通信する。クライアント300は、ユーザプログラム301とクライアントライブラリ303とを有する。ユーザプログラム301は共有ライブラリ化ユーザプログラム302を持つ。共有ライブラリ化ユーザプログラム302は、ユーザプログラム301が共有ライブラリとしてコンパイルされることにより得られる。クライアントライブラリ303は、ユーザ関数シンボル名取得部304と、ラッパ関数ポインタ取得部305、ラッパ関数シンボル名取得部306、シリアライズ部307、デシリアライズ部308、通信部309等を含む。ユーザ関数シンボル名取得部304は、関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得する。ラッパ関数ポインタ取得部305は、テンプレート関数として定義され、かつ、その内部でユーザ関数を実行するラッパ関数へのポインタを、ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得する。ラッパ関数シンボル名取得部306は、ラッパ関数へのポインタを用いて、ラッパ関数シンボル名を取得する。サーバ310はサーバライブラリ311を有する。サーバライブラリ311は、通信部312、ラッパ関数ポインタ取得部313、ラッパ関数実行部315等を含む。通信部31は、例えば、ユーザ関数シンボル名、ユーザ関数の引数に対応するデータ、ラッパ関数シンボル名、及び、ユーザプログラム及びラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムをクライアント300から取得する。ラッパ関数ポインタ取得部313は、通信部31により取得されたラッパ関数シンボル名を用いて、ラッパ関数へのポインタを取得する。ラッパ関数実行部315は、ユーザ関数ポインタ取得部316、ユーザ関数実行部319、デシリアライズ部317、シリアライズ部318等を含む。ラッパ関数実行部315は、これら各処理部を用いて、ユーザ関数シンボル名とシリアライズされたユーザ関数の引数に基づいてラッパ関数を実行する。サーバライブラリ311は、クライアント300から取得した共有ライブラリ化ユーザプログラム314をラッパ関数ポインタ取得部313および、ユーザ関数ポインタ取得部316からアクセスできる形で保持する。ユーザ関数ポインタ取得部316は、初期化時に取得された共有ライブラリ化ユーザプログラム314およびユーザ関数シンボル名により呼び出すべきユーザ関数へのユーザ関数ポインタを取得する。ユーザ関数実行部319は、ユーザ関数ポインタと引数を用いてユーザ関数を実行する。このような第一の実施形態におけるデータ処理システムの動作を説明する前に、ここで、上述の参考例と異なるラッパ関数について説明する。このラッパ関数を用いることにより、任意の型の引数、返り値を持つユーザ関数を実行することが可能となる。ラッパ関数の実現のため、本実施の形態では、Cのような、ジェネリックプログラミングの機能Cではテンプレートと呼ぶため以下テンプレートと記述するを使って関数を記述でき、かつ型を指定した関数の生成がコンパイル時に行われるプログラミング言語を用いる。例えば、Cのテンプレートを用いると、以下のような関数を記述できる。templateTaddreturnabこのような関数定義があった場合、addと記述した場合、データ型Tをdoubleとした関数addが利用され得る。これは、コンパイラが、doubleadddoublereturnabのような関数を内部で自動的に生成することで実現されている。このような機能を用い、第一の実施形態は、ユーザ関数をその中から呼び出すラッパ関数をテンプレート関数として導入する。そのテンプレート引数としてはユーザ関数の引数や返り値の型が定義される。ラッパ関数自身の引数や返り値は、これらの型に依存せず、固定のものとする。したがって、ラッパ関数自身は、上述の参考例と同様の方法でサーバ310側で呼び出せる。一方、ラッパ関数は、テンプレート引数として得られたユーザ関数の引数や返り値の型を用い、ユーザ関数をその引数や返り値の型に応じて実行する。これによって、任意の型の引数、返り値を持つユーザ関数を実行できるようになる。ラッパ関数は、引数として、ユーザ関数のシンボル名、ユーザ関数の引数をシリアライズしたものを取り、返り値としてシリアライズされたユーザ関数の返り値を返す。なお、ラッパ関数の返り値は、引数として取得されたポインタを用いて返されてもよい。以降の説明では、ラッパ関数の返り値は、返り値として返す例を用いる。ここで、シリアライズとは、複数の変数を一つのバイト列等に変換する操作である。シリアライズされたバイト列等から元の変数を復元する操作をデシリアライズと呼ぶ。ラッパ関数は、テンプレート引数に指定された型を用いて、シリアライズされたデータからユーザ関数の引数をデシリアライズして復元する。同様に、ラッパ関数は、テンプレート引数に指定された型を用いて、ユーザ関数の関数ポインタをその型に応じて取得する。そして、ラッパ関数は、この関数ポインタと引数を用いてユーザ関数を実行する。ユーザ関数の実行結果の返り値はシリアライズされラッパ関数の返り値として返される。このようなラッパ関数は、テンプレート引数に応じ、ラッパ関数ポインタ取得部305で、ラッパ関数へのポインタを取得する部分で、コンパイラによって生成される。したがって、ラッパ関数は、共有ライブラリ化ユーザプログラム302、314にも含まれる。このようなラッパ関数が定義されているとして、第一の実施形態の動作について説明する。まず、上述の参考例と同様に、ユーザはユーザプログラム301を記述し、ユーザプログラム301とクライアントライブラリ303とがリンクされる。ここで、クライアントライブラリ303の一部は上記のテンプレート関数として定義されている。例えばCの場合、ヘッダファイル内に定義されており、コンパイル時にも利用される。上述の参考例と同様に、ユーザプログラム301をコンパイルすると、コンパイルされたユーザプログラム301は共有ライブラリとしても保存される。これが、共有ライブラリ化ユーザプログラム302と表記される。ユーザプログラム301内では、上述の参考例と同様に、まず、初期化が行われる。この中で、ユーザプログラム301は、共有ライブラリ化ユーザプログラム302をクライアントライブラリ303に渡し、共有ライブラリ化ユーザプログラム302を通信部309を経由してサーバ310に送信する。サーバ310は、通信部312でこれを受信し、受信された共有ライブラリ化ユーザプログラムをサーバライブラリ311内に共有ライブラリ化ユーザプログラム314として保存する。続いて、ユーザプログラム301は、参考例と同様に、ユーザ関数ポインタと引数をクライアントライブラリ303に渡す。ここで、呼び出されるクライアントライブラリ303の関数は、テンプレート関数で実現され、ユーザ関数の引数や返り値の型をテンプレート引数として取る。クライアントライブラリ303では、ユーザ関数シンボル名取得部304が、そのユーザ関数ポインタが指す、オブジェクトファイル内におけるオブジェクトのシンボル名を取得する。クライアントライブラリ303は、ユーザプログラム301から与えられた引数に対し、シリアライズ部307においてシリアライズを行う。さらに、ラッパ関数ポインタ取得部305が、クライアントライブラリ303にテンプレート引数として与えられた型を指定して、ラッパ関数ポインタを取得する。そして、そのラッパ関数ポインタを用いて、ラッパ関数シンボル名取得部306が、ラッパ関数のシンボル名を取得する。通信部309は、ラッパ関数シンボル名、ユーザ関数シンボル名、シリアライズされた引数をサーバ310に渡す。サーバ310は、通信部312を経由してこれらを受け取る。サーバ310では、ラッパ関数ポインタ取得部313が、ラッパ関数シンボル名と共有ライブラリ化ユーザプログラム314から、ラッパ関数ポインタを取得する。サーバライブラリ311では、ラッパ関数実行部315が、この取得されたラッパ関数ポインタで特定されるラッパ関数を、ユーザ関数シンボル名と、シリアライズされたユーザ関数の引数とを引数として実行する。ラッパ関数は、上述したとおり、共有ライブラリ化ユーザプログラム314とユーザ関数シンボル名とからユーザ関数ポインタを取得する。また、ラッパ関数は、シリアライズされた引数をデシリアライズし、ユーザ関数の引数を取得する。ラッパ関数は、取得されたユーザ関数の引数を用いて、上記ユーザ関数ポインタにより特定されるユーザ関数を実行し、その返り値をシリアライズし、シリアライズされた返り値をラッパ関数の返り値として返す。シリアライズされた返り値は通信部312を経由してクライアント300に返される。クライアント300では、通信部309がこれを受け取り、デシリアライズ部308がその返り値をデシリアライズする。そして、デシリアライズされた返り値がユーザプログラム301に返される。次に、図3および図4を参照して、第一の実施形態の全体の動作について詳細に説明する。まず、ユーザプログラム301が、共有ライブラリ化ユーザプログラム302を指定して初期化を実行する図4のステップ401。これにより、クライアントライブラリ303が、共有ライブラリ化ユーザプログラム302をサーバ310に送信するステップ411。サーバライブラリ311は、これを受信しステップ421、受信された共有ライブラリ化ユーザプログラムをサーバライブラリ311に登録するステップ422。次に、ユーザプログラム301が、サーバ310でユーザ関数を実行するために、ユーザ関数ポインタと引数をクライアントライブラリ303に渡すステップ402。クライアントライブラリ303は、これを受け取りステップ412、ユーザ関数ポインタを用いてユーザ関数シンボル名を取得するステップ413。次に、クライアントライブラリ303は、取得された引数をシリアライズするステップ414。そして、クライアントライブラリ303は、ラッパ関数のポインタを取得しステップ415、ラッパ関数ポインタからラッパ関数シンボル名を取得するステップ416。クライアントライブラリ303は、ユーザ関数シンボル名、シリアライズされた引数、ラッパ関数シンボル名をサーバ310に送信するステップ417。サーバ310は、ユーザ関数シンボル名、シリアライズされた引数、ラッパ関数シンボル名を受信するステップ423。サーバライブラリ311は、受信されたラッパ関数シンボル名と共有ライブラリ化ユーザプログラム314とを用いてラッパ関数ポインタを取得しステップ424、ユーザ関数シンボル名とシリアライズされた引数を用いてラッパ関数を実行するステップ425。実行されたラッパ関数内では、まず、ユーザ関数シンボル名と共有ライブラリ化ユーザプログラム314に基づいて、ユーザ関数ポインタが取得されるステップ426。そして、シリアライズされた引数がデシリアライズされ、引数が復元されるステップ427。ラッパ関数は、これらを用い、ユーザ関数を実行するステップ428。ラッパ関数は、ユーザ関数の返り値をシリアライズするステップ429。このシリアライズされたユーザ関数の返り値は、ラッパ関数の返り値として返される、サーバライブラリ311は、シリアライズされたユーザ関数の返り値を、クライアント300に送信するステップ4210。クライアントライブラリ303は、シリアライズされた返り値を受信しステップ418、これをデシリアライズするステップ419。そして、クライアントライブラリ303は、このデシリアライズされた返り値をユーザプログラム301に返すステップ403。次に、上述の第一の実施形態の作用及び効果について説明する。上述の第一の実施形態では、任意の型の引数、返り値を持つユーザ関数を内部で呼び出すラッパ関数がテンプレート関数として定義され、ラッパ関数自身の引数、返り値の型が固定され、このラッパ関数がサーバ310側で呼び出される。これにより、第一の実施形態によれば、様々な型の引数、返り値を持つユーザ関数をサーバ310側で呼び出すことができる。上述の第一の実施形態におけるデータ処理システムでは、クライアント300側で共有ライブラリ化されたユーザプログラム302、及び、呼び出す関数のシンボル名がクライアント300からサーバ310に送信され、サーバ310側で、シンボル名と共有ライブラリ化したユーザプログラム302から呼び出すべき関数ポインタが取得され、ユーザ関数が実行されるというように、RPCが実現される。これにより、第一の実施形態によれば、CやCといったネイティブコードにコンパイルする言語を採用し、IDLを用いず、RPCを記述することができる。更に、第一の実施形態によれば、サーバ310側のプログラムとクライアント300側のプログラムを別々に記述することなく、RPCを実現することができる。その理由は、サーバ310は、ユーザプログラムによらないサーバライブラリ311を用い、共有ライブラリ化したユーザプログラム302314を受信することで、ユーザプログラム内で定義された関数をサーバ310側で実行するからである。更に、第一の実施形態によれば、OSレベルでの動作を想定していないので、OSの変更が必要なく、既存OS上で動作するライブラリとして実現することができるので、有用性が高い。第二の実施形態次に、第二の実施形態について図5を参照して詳細に説明する。第二の実施形態におけるデータ処理システムは、図5に示されるような、ハードウェア構成を持つ。クライアント500は、少なくとも1つのコンピュータ501、記憶媒体502等から構成され、サーバ510は、少なくとも1つのコンピュータ511、記憶媒体512等から構成される。コンピュータ501及び511は、相互に接続される、CPUCentralProcessingUnit、メモリ、入出力インタフェースI/F等を有する。記憶媒体502及び512は、例えば、ハードディスク、CD、DVD、ブルーレイ等のような媒体である。記憶媒体502及び512は、上述の第一の実施形態におけるユーザプログラム301、共有ライブラリ化ユーザプログラム302、クライアントライブラリ303、サーバライブラリ311等を格納する。コンピュータ501及び511は、記憶媒体502及び512に格納されるそれらプログラムを読出し、読み出されたプログラムをCPUで実行することにより、上述の第一の実施形態におけるデータ処理システムを実現する。第二の実施形態では、第一の実施形態におけるクライアントライブラリ303に含まれる、ユーザ関数シンボル名取得部304、ラッパ関数ポインタ取得部305、ラッパ関数シンボル名取得部306、シリアライズ部307、デシリアライズ部308、及び通信部309は、ソフトウェア要素として実現される。これらソフトウェア要素は、例えば、クライアントライブラリ303に含まれるモジュール又はコンピュータ501のOS図示せずで提供されるモジュールがCPUにより実行されることにより実現される。また、第二の実施形態では、第一の実施形態におけるサーバライブラリ311に含まれる、ラッパ関数実行部315、ラッパ関数ポインタ取得部313、通信部312、ユーザ関数実行部319、シリアライズ部318、デシリアライズ部317、ユーザ関数ポインタ取得部316も、ソフトウェア要素として実現される。これらソフトウェア要素は、例えば、サーバライブラリ311に含まれるモジュール又はコンピュータ511のOS図示せずで提供されるモジュールがCPUにより実行されることにより実現される。また、上述の第一の実施形態では特に明記はしなかったが、ユーザプログラム301、クライアントライブラリ303、サーバライブラリ311等を実行形式ネイティブコードに変換するソフトウェアであるコンパイラリンカ等も含むも、コンピュータ501又511は保持する。第一実施形態における各処理部が実現されるにあたり、これらコンパイラがコンピュータ501又は511で実行される。よって、第二の実施形態では、第一の実施形態の動作の説明における、動作主体ユーザプログラム301、クライアントライブラリ303、サーバライブラリ311、ラッパ関数などはCPUに置き換えることができる。この点、以下の実施例でも同様である。実施例次に、具体的な本発明の実施例の動作を図6から図14を用いて以下に説明する。ここでは、実施例として、LinuxOS上で実行される、C言語あるいはC言語により記述されたソースコードが例示される。但し、各図に示されるソースコードは、部分的に例示されたものであるため、そのまま動作するものではない。図6から図8に、第一の実施例が示される。図6はユーザプログラムを示し、図7はクライアントライブラリを示し、図8はサーバライブラリを示す。図6のユーザプログラムでは、userfunc1及びuserfunc2という関数ユーザ関数が定義されている。これらがサーバで実行したい関数である。参考例では、これらの関数の引数の数や型、返り値の型は固定となる。本参考例における各関数は、int型の引数を一つとり、int型の返り値を返す関数として定義されている。mainの中では、まずIPアドレス等を含むサーバの情報がNode型変数であるserverに取得される。Node型はライブラリ内で定義されているものとする。次に、関数initが呼び出されることにより、初期化が行われる。関数initの引数には、変数serverと、共有ライブラリ化ユーザプログラムのファイル名が渡される。すなわち、関数userfunc1及びuserfunc2が、共有ライブラリとしてこのファイル名で示されるファイル内に存在することになる。次の行の記述rpcにより、サーバ側で関数userfunc1が呼び出され、その返り値がrpc関数の返り値として得られる。この例の場合は2が返り値として返る。関数userfunc2についても同様に実行される。次に、図7を参照し、クライアントライブラリ303について説明する。クライアントライブラリ303では、ユーザプログラムから呼び出される関数initおよび関数rpcが定義されている。init関数が実行されると、サーバに共有ライブラリ化ユーザプログラムが送信される。そのため、init関数内では、まず、connecttoserver関数が実行されることにより、サーバへの接続が実現される。この実施例では、この関数は、Node型変数を受け取り、このNode型変数で示されるサーバに接続した後、ソケットを示すファイルディスクリプタを返す。次に、ファイル名で指定された共有ライブラリ化ユーザプログラムが、raedfromfile関数により読み取られる。この関数は、ファイルからその内容を読み取り、読み取られた内容を第一引数で与えられたchar型のポインタが指すメモリ領域に書き込む。なお、ここでは、変数の宣言やメモリ確保及び解放などは省略されている。そして、読み込んだバイト数が戻される。次に、writetosocket関数がサーバにファイルの内容を送信する。この関数は、ソケットと送信すべきデータが入ったchar型のポインタ、およびそのサイズを指定することで、データをサーバに送信する。最後に、closeconnection関数が呼び出される。この関数は、connecttoserver関数で作成されたソケットをクローズする。次に、rpc関数について説明する。rpc関数の中では、getsymbol関数が利用されているため、これについて、まず説明する。getsymbol関数は、関数ポインタを受け取り、OSが提供するdladdr関数を呼び出すことで、関数ポインタのシンボル名を取得する。dladdr関数には、関数ポインタと、OSが定義するDlinfo型の変数へのポインタを渡すことで、Dlinfo型変数のdlsnameメンバにその関数のシンボル名が返される。次にrpc関数の動作について説明する。rpc関数は、上述のgetsymbol関数を用い、引数として与えられた関数ポインタのシンボル名を取得する。次に、上述と同様にconnecttoserver関数を用いてサーバに接続し、ソケットのファイルディスクリプタを取得する。そして、rpc関数は、writetosocket関数を用いて、まず、ユーザ関数シンボル名をサーバに送信する。そのため、引数に、ソケットのファイルディスクリプタ、ユーザ関数シンボル名、及びそのサイズが渡される。次に、rpc関数は、引数をサーバに送信する。そのため、writetosocket関数の引数として、ファイルディスクリプタと、引数をchar型のポインタ型にキャストしたもの、そしてsizeofこの例ではint型が渡される。次に、rpc関数は、readfromsocket関数を用い、実行結果をサーバから受け取る。この関数は、ソケットのファイルディスクリプタと、char型のポインタを受け取り、実行結果のデータをサーバから受け取る。続いて、rpc関数は、変数retに、サーバから受け取った値変数bufの値をint型にキャストした上で設定する。最後に、rpc関数は、closeconnection関数でソケットをクローズし、変数retの値をrpc関数の返り値として返す。次に、図8を参照してサーバライブラリの動作について説明する。サーバライブラリでは、まず、acceptconnection関数が、クライアントからの接続を受け付ける。図8の例では、この関数は、クライアントによるconnecttoserver関数の実行に応答し、接続を確立する。この関数は、返り値として、ソケットのファイルディスクリプタを返す。なお、接続ごとにプロセスがフォークされ、接続ごとに別プロセスが生成されてもよい。この場合、親プロセスは、acceptconnection関数の実行に戻り、子プロセスは以下の処理を行う。サーバは、この接続を用い、クライアントから共有ライブラリ化ユーザプログラムをreadfromsocket関数で受信する。readfromsocket関数は返り値として読み込んだバイト数を返す。次に、メモリ上に読み込んだ共有ライブラリ化ユーザプログラムをファイルに書き込むためwritetofile関数が呼び出される。この関数は、ファイル名と、共有ライブラリ化ユーザプログラムが読み込まれたメモリ領域へのポインタ、そのサイズを指定して、共有ライブラリ化ユーザプログラムを引数のファイル名により示されるファイルに書き込む。ここでは、書き込み先のファイル名としてtmptmpfilesoが指定されている。そして、OSが提供する関数であるdlopenにより、この共有ライブラリがオープンされる。引数には書き込まれたファイルのファイル名と、dlopenの動作を決めるフラグが指定されるここではRTLDLAZYを指定している。dlopenの返り値はハンドルであり、これを後で利用する。そして、closeconnection関数が呼び出され、クライアントとの接続がクローズされる。この後、サーバはクライアントからのユーザ関数実行要求を受け付けるためのループを実行する。まず、サーバは、acceptconnection関数により、クライアントからの接続を受け付ける。なお、あるユーザ関数実行中にも他のユーザ関数実行要求を同時に受け付けるため、以下のユーザ関数実行のための処理が別スレッドで行われるようにしてもよい。この場合、親スレッドは、acceptconnection関数の実行に戻り、生成されたスレッドが以下の処理を行う。プロセスではなくスレッドを用いることで、ユーザ関数がグローバル変数に値を設定した場合などに、後で呼び出すユーザ関数呼び出しからその値を利用することができるようになる。次に、readfromsocket関数で、ユーザ関数シンボル名が受信される。更に続くreadfromsocket関数で、引数が受信される。引数は、int型にキャストされる。続く、typedefは、呼び出す関数の型をfunctypeとして定義する。この実施例では、functypeは、int型の値を引数にし、int型の値を返す関数へのポインタ型として定義されている。そして、サーバは、OSが提供する関数であるdlsymを呼び出すことで、呼び出すべき関数へのポインタを取得する。dlsym関数の引数は、dlopen関数の実行によって得られたハンドルと、関数のシンボル名である。dlsym関数の返り値として関数へのポインタが得られるので、このポインタがfunctype型の変数にキャストされ、代入される。そして、サーバは、この関数へのポインタに対し、引数を与えることにより、当該関数を実行する。この関数の返り値は、writetosocket関数によって、クライアントに送信される。最後に、サーバは、closesocket関数で接続をクローズし、ループの先頭に戻る。次に、第二の実施例について図9から図14を用いて説明する。図9はユーザプログラムを示し、図10から図13はクライアントライブラリを示し、図14はサーバライブラリを示す。まず、図9のユーザプログラムについて説明する。これは第一の実施例とほとんど同じであるが、サーバで呼び出される関数の型および引数の数が変更可能になっている。すなわち、userfunc1関数は、int型の引数を一つとり、int型の値を返す関数であるが、userfunc2関数は、double型の引数を二つとり、double型の値を返す関数である。また、第二の実施例では、後述するとおり、rpc関数はテンプレート関数として実現されているが、コンパイラがデータ型を推論することが可能なため、呼び出し時にrpcのようにデータ型を指定する必要は無い。次に、図10から図13を用いてクライアントライブラリを説明する。図10及び図11はユーザ関数の引数の数が一つの場合の定義を示し、図12及び図13はユーザ関数の引数の数が二つの場合の定義を示す。このように、第二の実施例では、ユーザ関数の引数の数に応じて、関数の定義が複数用意される。ここでは引数の数が二つまでを示すが、それ以上の引数の数に対応するためには、単純に引数の数を増やした定義が追加されれば良い。図10および図12はラッパ関数であるwrapperの定義である。図11および図13はrpc関数の定義である。まず、図10のwrapper関数について説明する。wrapper関数はテンプレート関数として定義されている。図10の例は、ユーザ関数の引数の数が一つの場合の定義を示すため、テンプレート引数として、ユーザ関数の返り値のデータ型Rと、引数のデータ型T1が指定されている。wrapper関数の引数は、ユーザ関数のシンボル名が設定されるsymbol、dlopen関数によって得られるハンドルが設定されるhandle、シリアライズされた引数であるinput、シリアライズされた返り値であるoutputである。シリアライズされた返り値は、wrapper関数の中で作成され、呼び出し元に返されるため、outputはポインタ引数である。第二の実施例では、Boostと呼ばれるライブラリ群により提供されるシリアライズライブラリを用いてシリアライズ機能が実現される例を説明するライブラリのバージョン135を元に説明する。変数inputの型はbinaryiarchiveであり、変数outputの型はbinaryoarchiveであり、これらは、Boostのシリアライズライブラリが提供しているデータ型である。binaryiarchive型変数は、シリアライズされたデータをデシリアライズするために、binaryoarchive型変数は、変数をシリアライズするために用いられる。wrapper関数の中では、まず、ユーザ関数の型がtypedefを用いてfunctypeとして定義される。図10の例では、functypeは、T1型の引数を取り、R型を返り値とする型として定義される。そして、ユーザ関数のシンボル名が設定されるsymbolと、dlopen関数によって得られるハンドルが設定されるhandleとを引数としてdlsym関数が呼び出されることで、ユーザ関数ポインタが取得される。これがfunctype型にキャストされ、変数fに代入される。更に、引数のデータ型であるT1型の変数a1、及び、返り値のデータ型であるR型の変数retが定義される。そして、引数である変数inputがデシリアライズされたデータが、変数a1に代入される。Boostのシリアライズライブラリでは、このデシリアライズ操作は>>として定義されている。続いて、変数a1を引数としてユーザ関数fが実行され、返り値が変数retに保存される。返り値となる変数outputには、変数retがシリアライズされたデータが入力される。このシリアライズ操作はBoostのシリアライズライブラリでは<<として定義されている。次に、図11を参照して、rpc関数について説明する。rpc関数もテンプレート関数として定義されている。図11の例は、ユーザ関数の引数の数が一つの場合の定義を示すため、テンプレート引数として、ユーザ関数の返り値のデータ型Rと引数のデータ型T1が指定されている。rpc関数の引数は、第一の実施例の場合と同様であるが、rpc関数がテンプレート関数として定義されているため、引数のデータ型に制約は無い。rpc関数の中では、まず、ラッパ関数ポインタが取得される。このとき、テンプレート引数として与えられたデータ型が、wrapperと指定されることで、そのデータ型に応じたラッパ関数ポインタが取得される。コンパイラは、このラッパ関数ポインタが取得された時点で、テンプレート引数RT1に応じたwrapper関数の定義を作成する。次に、上記で得られたラッパ関数のシンボル名が取得される。これには第一の実施例で用いたgetsymbol関数が利用される。次に、rpc関数の引数として与えられたユーザ関数ポインタを引数としてgetsymbol関数を呼び出すことで、ユーザ関数シンボル名が取得される。そして、引数a1がシリアライズされる。Boostのシリアライズライブラリでは、シリアライズした結果をstring型として受け取る場合、標準ライブラリのostringstream型の変数を引数として、binaryoarchive型の変数が定義される。ここでは、ostringstream型の変数osが定義され、それを用いてbinaryoarchive型の変数inputが定義されている。そして、上述と同様、<<を用いて引数a1がシリアライズされる。次に、rpc関数は、connecttoserver関数を用いてサーバに接続する。このconnecttoserver関数により得られたソケットのファイルディスクリプタを引数としてwritetosocket関数に与えることにより、ユーザ関数シンボル名が送信される。次に、シリアライズされた引数が送信される。シリアライズされた結果は、ostringstream型変数osに設定されているので、strメンバ関数でまずstring型として取り出され、さらに、cstrメンバ変数でchar型のポインタとして取り出される。シリアライズされた結果のサイズは、それをstring型として取り出して、lengthメンバ関数を呼び出すことにより得ることができる。続いて、ラッパ関数シンボル名が送信される。その後、シリアライズされた返り値がreadfromsocket関数で取得される。この取得されたデータをデシリアライズするため、そのデータをstring型に変換したものを引数として用いて標準ライブラリのistringstream型の変数isが定義される。そして、変数isを引数として用いて、binaryiarchive型の変数outputが定義される。返り値を保存する変数retが定義され、上述と同様に、>>を用いて変数outputをデシリアライズしたデータが変数retに設定される。最終的に、closeconnection関数によりサーバとの接続がクローズされ、返り値retがユーザプログラムに返される。図12および図13はユーザ関数の引数の数が二つの場合の定義を示す。以下、図12のwrapper関数について、図10で示されたユーザ関数の引数の数が一つの場合の定義との違いを中心に説明する。この場合、テンプレート引数は、返り値1つと引数2つとの合計3つになる。また、ユーザ関数の型において、引数の数が異なっている。これにより、引数のデシリアライズが2引数分になり、ユーザ関数も、2つの引数を用いて、呼び出されている。関数の名前はwrapperであり、図10で示された引数が一つの場合と同じであるが、Cにおいて、これは許されている。次に、図13のrpc関数について、図11で示されたユーザ関数の引数の数が一つの場合の定義との違いを中心に説明する。wrapper関数の場合と同様、テンプレート引数が返り値1つと引数2つの合計3つになる。また、rpc関数自身の引数に関しても、ユーザ関数の引数が二つになるのに伴い、ユーザ関数ポインタの型が変更になり、またユーザ関数の引数が追加されている。wrapper関数ポインタを取得する部分でも、テンプレート引数の数が3つになっている。そして、引数をシリアライズする部分で、二つの引数がシリアライズされている。上述のように、図10から図12への変更及び図11から図13への変更と同様の変更を加えることによって、三つ以上の引数を持つユーザ関数についても定義を記述することが可能となる。次に、図14を参照してサーバライブラリについて説明する。サーバライブラリは、引数の数によらず、同じものが用いられる。初期化の部分は第一の実施例と同じである。while文の中では、まず、クライアントからの接続がacceptconnection関数で受け付けられる。ここで得られたソケットのファイルディスクリプタを用い、クライアントからユーザ関数のシンボルと、シリアライズされた引数が取得される。続いて、binaryiarchive型変数を作るため、取得された引数bufをstring型に変換したデータを引数として用いることにより、istringstream型の変数isが定義される。更に、この変数isを引数として用いることにより、binaryiarchive型の変数inputが定義される。この変数inputは、後でwrapper関数の引数とされる。次に、ラッパ関数シンボル名がクライアントから取得される。これを元に、ラッパ関数ポインタがdlsym関数を用いて取得される。そして、ostringstream型の変数osが定義され、この変数osを引数にbinaryoarchive型の変数outputが定義される。この変数outputは、wrapper関数の引数として、返り値をシリアライズした内容を受け取るために用いられる。そして、先ほど取得したwrapper関数のポインタを用いて、wrapper関数が実行される。このとき、wrapper関数の引数には、ユーザ関数シンボル名symbol、dlopen関数によって得られたハンドルhandle、シリアライズされた引数を内部に持つ、binaryiarchive型の変数input、ユーザ関数の返り値をシリアライズしたものを保存するためのbinaryoarchive型の変数outputへのポインタが与えられる。wrapper関数が実行されると、上述のwrapper関数の定義通り、引数がデシリアライズされ、ユーザ関数シンボル名からユーザ関数ポインタが取得され、デシリアライズした引数を用いてユーザ関数が実行され、返り値がシリアライズされて変数outputに入れられる。これにより、wrapper関数終了後、シリアライズされた返り値の内容がクライアントに送信される。このとき、ostringstream型の変数osからstrメンバ関数でstring型のデータが取り出され、さらにcstrメンバ関数で、char型のポインタとしてデータが取り出される。取り出されるデータのサイズは、変数osのメンバ関数strにより取り出されたstring型のデータに対して、lengthメンバ関数を呼び出すことで得られる。これらを引数にwritetosocket関数を呼び出すことで、クライアントにシリアライズされた返り値の内容が送信される。なお、本発明は本実施の形態に限定されるものではなく、その要旨を逸脱しない範囲で各種の変形を許容する。例えば、本発明は、ネットワークで結合された複数のサーバ上で並列に実行するプログラムを記述する用途に適用できる。また、ネットワークで結合された別のサーバ上の資源ファイル等を利用するプログラムを記述する用途にも適用可能である。なお、当然ながら、上述した実施の形態および複数の実施例は、その内容が相反しない範囲で組み合わせることができる。また、上述した実施の形態および実施例では、各部のプログラムなどを具体的に説明したが、そのプログラムなどは本願発明の要旨を逸脱しない範囲で各種に変更することができる。この出願は、2010年6月17日に出願された日本出願特願2010-138398号を基礎とする優先権を主張し、その開示の全てをここに取り込む。