I'll give you an example for math functions that can be called via RPC.
First you need to create a file that describes the RPC functions. Here's mycal.x:
Code:
struct mycal_in {
double arg1;
double arg2;
};
struct mycal_out {
double res1;
};
program MYCAL_PROG {
version MYCAL_VERS {
mycal_out ADDPROC(mycal_in) = 1;
mycal_out SUBTRACTPROC(mycal_in) = 2;
mycal_out MULTIPLYPROC(mycal_in) = 3;
mycal_out DIVIDEPROC(mycal_in) = 4;
} = 1;
} = 0x53778892;
You use rpcgen to compile this and produce mycal.h (among others) that is included in your client and server. You'll have to look at mycal.h to see the prototypes for the functions that you have to implement.
Code:
rpcgen -N -C mycal.x
You'll have other outputs from rpcgen that will need to be compiled and linked into your application: mycal_xdr.c and mycal_svc.c need to be compiled and linked into your server program whereas mycal_xdr.c and mycal_clnt.c need to be compiled and linked into your client program.
Now write the functions for the server. Here's mycal_server.c:
Code:
#include "mycal.h"
#include <stdio.h>
#include <stdlib.h> /* getenv, exit */
#include <signal.h>
mycal_out *
addproc_1_svc(mycal_in arg1, struct svc_req *rqstp)
{
static mycal_out result;
/*
* insert server code here
*/
result.res1 = arg1.arg1 + arg1.arg2;
return (&result);
}
mycal_out *
subtractproc_1_svc(mycal_in arg1, struct svc_req *rqstp)
{
static mycal_out result;
/*
* insert server code here
*/
result.res1 = arg1.arg1 - arg1.arg2;
return (&result);
}
mycal_out *
multiplyproc_1_svc(mycal_in arg1, struct svc_req *rqstp)
{
static mycal_out result;
/*
* insert server code here
*/
result.res1 = arg1.arg1 * arg1.arg2;
return (&result);
}
mycal_out *
divideproc_1_svc(mycal_in arg1, struct svc_req *rqstp)
{
static mycal_out result;
result.res1 = 0;
if( arg1.arg2 ) {
result.res1 = arg1.arg1 / arg1.arg2;
}
return (&result);
}
Finally you need to write the client that calls these functions. It too will have mycal.h #included. My C++ program implemented a parser for an LL(1) grammar that recognizes valid arithmetic expressions, constructed a parse tree of the expressions, then traversed the parse tree to evaluate the expressions. Evaluating an expression involves making calls to the RPC math functions. Here's one method used in the expression evaluation:
Code:
double ParseTree::doDivide( double a, double b )
{
CLIENT* client;
mycal_in in;
mycal_out* out;
double result = 0;
if( b != 0 ) {
in.arg1 = a;
in.arg2 = b;
client = clnt_create(hostname, MYCAL_PROG, MYCAL_VERS, "tcp");
if( client == NULL ) {
throw ParseTreeError( "Failed to create RPC client for divide()." );
}
out = divideproc_1( in, client );
if( out == NULL ) {
throw ParseTreeError( "Failed RPC to divide()." );
}
clnt_destroy( client );
result = out->res1;
}
else{
throw ParseTreeError("Divide by zero not allowed.");
}
return( result );
}
If you want all of my code, send me an email and I'll send you everything I have.