Распределенные вычисления и технологии Inprise

       

Создание серверной части (C/C++)


В результате использования утилиты rpcmake.exe (или rpcmgui.exe) с парамерами, соответствующими выбору C или C++ в качестве языка для сервера, получим следующие файлы: a1_c.c (stub-код, который можно встраивать в клиентское приложение), a1_s.c (исходный текст консольного приложения для сервера функциональности), a1_s.h - h-файл для myserv_s.c, a1.h - h-файл, содержащий объявления функций без их реализации (используется в клиентском приложении). Реализацию этих функций (a1.c) следует создать разработчику.

Код для сервера a1.с, сгенерированный этой утилитой, выглядит следующим образом:

/*######################## # Server Proxy Procedure Code # generated by rpcmake version2.0 # on Thursday, December 31, 1998 at 19:17:39 # # interface: a1 #

######################## # server stub routines # ########################*/ #ifdef __mpexl #include "dceinc.h" #else #include <dceinc.h> #endif

#include <stdio.h> #include <stdlib.h> #include <string.h>

#ifdef __cplusplus extern "C" { #endif

/* RPC stub and stub handle definitions */ void rpc_handle (char *, struct table *, int); void rpc_sin1 (struct table *, int); #ifdef __cplusplus } #endif void rpc_sin1 (struct table *dce_table,int Socket) { double x; int _i; double sin1(double);

x = dce_pop_double(dce_table,"x"); dce_push_double(Socket,"dce_result", sin1(x)); }

int main(int argc,char **argv) { char *ode_file = NULL,*ode_server = NULL; char dce_func[VARLEN]; struct table *dce_table; int called_init_func = 0; int socket,rsocket;

if (!parse_args(&argc, argv,&ode_file)) { printf ("Env flag (-e) not set\n"); ode_file = argc > 1 ? argv[argc-1] : (char *) NULL; } if (dce_setenv(ode_file,NULL,NULL) == 0) { fprintf(stderr,"Set env %s failed\n", ode_file); fprintf (stderr,"Reason: %s\n", dce_errstr()); exit(1); } ode_server = dce_servername("a1");

dce_checkver(2, 0);

if ((socket = dce_init_server( ode_file,ode_server)) <= 0) { fprintf (stderr,"setup server failed\n"); fprintf (stderr,"Reason: %s\n", dce_errstr()); dce_set_exit(); }


while(1) { dce_table = dce_waitfor_call(socket,dce_func); if (dce_should_exit() dce_err_is_fatal() ) {break; } else{ if (dce_server_is_ded()) { dce_spawn(socket,argc,argv,ode_file,ode_server); socket = dce_retsocket(); /* save for future */ } rsocket = dce_retsocket(); /* (old socket closed) */ rpc_handle(dce_func,dce_table,rsocket); dce_send(rsocket,dce_func); dce_recv_conf(rsocket); dce_release(); dce_table_destroy(dce_table); if (!dce_server_is_ded()) { dce_close_socket(rsocket); } } } dce_close_socket(rsocket); dce_table_destroy(dce_table); return(0); }

void rpc_handle(char *func,struct table *dce_table, int Socket) { if (strcmp(func,"sin1")==0) (void)rpc_sin1(dce_table,Socket); else (void)dce_unknown_func(func, dce_table, Socket); }

H-файл a1_s.h выглядит следующим образом:

/************************************* * * Server Header for a1 * Generated by rpcmake version 3.0 * on Thursday, December 31, 1998 at 19:17:39 * **************************************/ #ifdef __cplusplus extern "C" { #endif

extern double sin1(double ); #ifdef __cplusplus } #endif

Код реализации функции следует создать разработчику. Он должен иметь примерно следующий вид:

USEUNIT("A1_s.c"); USELIB("odet30.lib"); //----------------------------------------------------------------- double sin1(double x) { int ii; double xx,r,sl,f,delta=0.0001; sl=x; ii=1; r=0; xx=x*x; f= fabs(sl); while (f>delta) { r=r+sl; sl=-(sl*xx/(2*ii))/(2*ii+1); f=fabs(sl); ii=ii+1 ; } return(r); }

Отметим, что все функции, связанные с выделением памяти в обычном С-коде, следует заменить на соответствующие функции c префиксом dce_ (например, dce_malloc) из Entera API.


Содержание раздела