Writing your first C module

From AOLserver Wiki
Revision as of 16:05, 3 December 2005 by Caveman (talk | contribs) (created tutorial)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Writing your first C Module

The AOLServer C API is very easy to develop towards. This short tutorial takes you through construction of an "nshello" module that provides a "ns_hello" function.

Step 1: Write your module code, "nshello.c" (this can be any name you like):


/*
 * Get the data types and constants you will need later on,
 * such as Tcl_Interp and NS_OK.
 */
#include "ns.h"

#include <string.h>
#include <sys/types.h>

/*
 * Each module asserts its version via the required Ns_ModuleVersion variable
 */
int Ns_ModuleVersion = 1;

/*
 * Declare that this module will implement this initialization method.
 */
int Ns_ModuleInit(char *hServer, char *hModule);

/*
 * This can be named whatever you like, it is used during module initialisation
 * to contain specific initialisation steps for the Tcl interpreter itself,
 * such as registering commands like "ns_hello".
 */
static int HelloInterpInit(Tcl_Interp *interp, void *context);

/*
 * Declare a C function that will be bound to the "ns_hello" Tcl command.
 */
static int HelloCmd(ClientData context, Tcl_Interp *interp, int argc, char **argv);


/*
 * Implement the Ns_ModuleInit function we declared we would implement earlier.
 * This is called by the server right after the module is loaded. Here, you
 * can read configuration data, initialise internal data, and of course
 * register any Tcl commands.
 */
int Ns_ModuleInit(char *hServer, char *hModule)
{

    /*
     * Invoke the server's Tcl interpreter initialisation and pass
     * it the callback we defined to our own interpreter initialisation.
     */
    return (Ns_TclInitInterps(hServer, HelloInterpInit, NULL));

}

/*
 * Implement the interpreter initialisation we declared and passed
 * during module init. Use Tcl_CreateCommand to register
 * the command "ns_hello", passing a callback to "HelloCmd" which
 * we declared earlier.
 */
static int HelloInterpInit(Tcl_Interp *interp, void *context)
{
    Tcl_CreateCommand(interp, "ns_hello", HelloCmd, NULL, NULL);

    return NS_OK;
}


/*
 * Append "hello" and then all arguments to the result.
 */
static int HelloCmd(ClientData context, Tcl_Interp *interp, int argc, char **argv)
{
    int i;

    Tcl_AppendResult(interp, "hello", NULL);

    for (i = 0; i < argc; i++)
    {
           Tcl_AppendResult(interp, " ", NULL);
           Tcl_AppendResult(interp, argv[i], NULL);
    }

    return NS_OK;
}

That's it. That's an entire module.

Step 2: Build your module.

AOLServer includes a meta-Makefile Makefile.module that simplifies the construction of module makefiles. Simply define a few values in your owm Makefile, then include this meta-Makefile.


#
# Module name
#
MOD      =  nshello.so

#
# Objects to build
#
OBJS     =  nshello.o

#
# Header files in THIS directory
#
HDRS     =

#
# Extra libraries
#
MODLIBS  =


#
# Compiler flags
#
CFLAGS   =

include  /usr/lib/aolserver4/Makefile.module

Done. Now you can build your module with 'make'.

You should now have a nifty "nshello.so" shared object library sitting around. Copy "nshello.so" to /usr/lib/aolserver4/bin (or where you keep your server modules).

Step 3: Tell aolserver to load the module (/etc/aolserver4/aolserver4.tcl):

ns_section "ns/server/${servername}/modules"
ns_param   nshello            nshello.so

Done. Restart aolserver and check the log file for errors.

Step 4: Use the function "ns_hello" in an ADP script:

<%
ns_adp_puts [ns_hello "AOLServer module" "world!"]
%>

Whoa! You get a strange result: hello ns_hello AOLServer module world!

Notice that "ns_hello" in there? That's because argv[0] is actually the name of the function used to call your interpreter! So, keep that in mind and happy AOLServer module hacking!