|
C API REFERENCE
QUESTIONS/COMMENTS/BUGS:
michaelcollins@ivorycity.com
DOWNLOAD:
xwspc-1.0.4.tar.gz
xwspclient_example.tar.gz
METHOD SUMMARY:
| XWSPClient* |
XWSPClient_new |
( char* hostname, char* application, char* file); |
| dsany |
XWSPClient_call |
( XWSPClient* xwspc, XWSPService* svce, ... ); |
| void |
XWSPClient_setHostContext |
( XWSPClient* xwspc, char* hostname ); |
| void |
XWSPClient_setApplicationContext |
( XWSPClient* xwspc, char* application_name ); |
| void |
XWSPClient_setFileContext |
( XWSPClient* xwspc, char* filename ); |
| char* |
XWSPClient_getErrStr |
( XWSPClient* xwspc ); |
| void |
XWSPClient_destroy |
( XWSPClient* xwspc ); |
USER DATA STRUCTURES:
struct XWSPService
{
char* objname; /*Name of the object you want to call*/
char* methodname; /*Name of the method within the object*/
int argtypes[16]; /*Up to 15 arguments (0 terminated) of
the specified types*/
};
Argument types are:
| INTARG |
An integer argument |
|
| FLOATARG |
A floating point number argument |
|
| DOUBLEARG |
A double precision float argument |
|
| STRINGARG |
A string (char* type) argument |
|
| DSANYARG |
A DSANY argument for complex data types, see the ds api |
|
OVERVIEW:
If you've already looked over the Perl API reference, you'll notice
that the C API uses a different object name, XWSPClient. Don't sweat
it. XWSPClient is actually a more accurate name and serves the same
purpose as PService. XWSP is the transport protocol for the
mod_perlservice system. If you want to learn more about it, check out
the internals page. But it doesn't have
any relevence to how the system works, and that's what you're here for,
so lets get started.
Now you're a C programmer so you probably know that all the magic
available to us in Perl probably won't be available to us in C, but we
do have a few pretty neat tricks left.
Here's the crux:
#include "XWSPClient.h"
XWSPService hello = { "myservice", "hello", {STRINGARG,0} };
int
main()
{
XWSPClient* xwspc =
XWSPClient_new("www.somehost.com","someapplication","somefile.pm");
dsany retds = XWSPClient_call( xwspc, &hello,
"This is my string argument" );
XWSPClient_destroy(xwspc);
}
The above code first defines a global service called hello. If you look
at the definition of struct XWSPService, it consists of an object name,
a method name, and an argument list. 'hello' is defined as server
method "hello" in package myservice, and we have indicated that we
intend to pass it a string when we call it.
In main, we construct a XWSPClient object and initialize the host name,
application name and file name to "www.somehost.com",
"someapplication", and "somefile.pm" respectively. Now, we're ready to
start calling the server, so we pass a pointer to the 'hello'
XWSPService structure as the second argument of XWSPClient_call, and
one string argument, as we indicated we would. The XWSPClient will now
call myservice::hello on the remote server and store the return value
back in retds. Make sure you pass the same number of arguments and the
correct types that you indicated in your XWSPService definition!
Otherwise you'll probably crash.
One other note, XWSPService structures do not have to be static. You
can malloc them or create them on the stack, so you have quite a bit of
runtime flexibility. You may want to consider this if you have a
particularly large number of server side methods.
At this point, you may want to learn more about how dynamic, and
complex data structures are implemented in this system. This is managed
by the ds api (ds for data structures). The documentation can be found here.
METHOD
DOCUMENTATION
| XWSPClient*
XWSPClient_new(char* hostname, char* application, char* file); |
Construct a new XWSPClient object.
USAGE
XWSPClient* xwspc = XWSPClient_new( "www.somehost.com",
"someapplication", "somefile.pm");
ARGUMENTS
| char* hostname |
The fully qualified domain name or ip of the server
running apache and mod_perlservice |
| char* application |
The alias name of the application you wish to use, see mod_perlservice docs for more. |
| char* file |
The name of the file that contains the code you want to
use. |
| dsany
XWSPClient_call(XWSPClient* xwspc, XWSPService* svce, ... ); |
Call the sub routine on the server using the pre-set server,
application, and file contexts set in the XWSPClient structure, and
object and method set in the XWSPService. This method takes a variable
number of arguments, but make sure you pass the same number and type of
args you specified in the service definition, or else you might crash.
Your arguments will be encoded and sent along with your request, where
they will magically appear in the server method's @_. One of the most
useful and important features of this system is the ability to pass
complex nested data structures as arguments and recieve the same as
return values. You can accomplish this through passing dsany types
which may include arrays of hashes or hashes mixed with arrays,
scalars, and hashes. See the ds api for more
on this.
If an error occurs during the call, the function returns an empty dsany
and an error message is set, see XWSPClient_getErrStr.
USAGE
XWSPService hello1 =
{"somepackage","hello",{STRINGARG,FLOATARG,INTARG,0}};
XWSPService hello2 = {"somepackage","hello",{DSANY,0}};
dsany retval = XWSPClient_call(xwspc,&hello1,"My String", 3.14, 42);
switch(retval.type)
{
| case DSSTRING: |
printf("\nString return: %s", retval.any.stringType);
break; |
| case DSINT: |
printf("\nInt Return: %d", retval.any.intType); break; |
| case DSFLOAT: |
printf("\nFloat return: %f", retval.any.floatType);
break; |
| case DSANYARRAY: |
dsany vzero;
dsanyarray_get(retval.any.dsanyarrayType,4,&vzero);
printf("\ndsanyarray return: %s", vzero.any.stringType);
break; |
| case DSTABLE: |
dsany qrslt;
dsquery(retval,"users.wonder.[4].rating");
printf("\nqueried table returned: %d rating", qrslt.any.intType);
break; |
}
retval = XWSPClient_call(xwspc,&hello2,retval);
if(dsany_isstring(retval)) printf("\nServer Said: %s", dsS(retval) );
ARGUMENTS
| XWSPClient* xwspc |
Your xwspc object. |
| XWSPService* svce |
Any defined XWSPService where package and method can be
found in the resources defined in your xwspc object. |
| [...] |
The variable arguments as defined in the XWSPService |
| void
XWSPClient_setHostContext ( XWSPClient* xwspc, char* hostname ); |
Change the name of the host where mod_perlservice can be found. Now,
when you call a remote method, the XWSPClient will connect to the new
server.
USAGE
XWSPClient_setHostContext(xwspc,"www.newhost.com");
ARGUMENTS
newhostname: The domain name or IP address of the server where your
application files can be found.
| void
XWSPClient_setApplicationContext( XWSPClient* xwspc, char*
application_name ); |
Change the name of the application you're using. The application is
basically the working directory where your files are found.
USAGE
XWSPClient_setApplicationContext(xwspc,"my_new_app");
ARGUMENTS
newappname: The name of the application you want to start using.
| void
XWSPClient_setFileContext( XWSPClient* xwspc, char* filename ); |
Change the name of the file you're using. The file contains the
packages/objects and methods you want to use.
USAGE
XWSPClient_setFileContext(xwspc,"my_file.pm");
ARGUMENTS
newfilename: The file you want to start using.
| char*
XWSPClient_getErrStr( XWSPClient* xwspc ); |
In the event that a remote method call fails, the return value will be
an empty dsany and an error message will be set. Use
XWSPClient_getErrStr to get a text representation of the error.
USAGE
char* err = XWSPClient_getErrStr(xwspc);
| void
XWSPClient_destroy( XWSPClient* xwspc ); |
Clean up the XWSPClient object, and free memory.
USAGE
XWSPClient_destroy(xwspc);
|