From Ape Wiki

Jump to: navigation, search

[edit] How to build server-side module in C to use with Javascript

Building a server-side javascript module is documented here (http://www.ape-project.org/wiki/index.php/How_to_create_a_server_Module), while building server-side modules in C is considered deprecated or at least not the best idea (it is not documented at all!). Programing in javascript is all fancy and stuff, but what are you supposed to do if you need Postgres, Memcached or something like that? For C (and C++) there is tons of libraries available, APE-Project is based on C, so maybe we could do something about that. Read on if you’re interested.

We are going to make a javascript (mootools) class in C, like for example mysql class that is already there. For this example I’m going to create “Memcached” class.

First we need some structures:

struct _ape_memcached_data {
    memcached_st *server;
    JSObject *jsmemcached;
    JSContext *cx;
};
static JSClass memcached_class = {
    "Memcached", JSCLASS_HAS_PRIVATE,
        JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
        JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
        JSCLASS_NO_OPTIONAL_MEMBERS
};
static JSFunctionSpec apememcached_funcs[] = {
    JS_FS("get", apememcached_sm_get, 2, 0, 0),
    JS_FS_END
};
static JSFunctionSpec apememcached_funcs_static[] = {
    JS_FS_END
};

We also need the actual functions that are going to be called from javascript:

APE_JS_NATIVE(ape_sm_memcached_constructor)
//{
    char *host;
    int port;
 
    struct _ape_memcached_data *myhandle;
 
    if (!JS_ConvertArguments(cx, argc, argv, "si", &host, &port)) {
        return JS_TRUE;
    }
 
    myhandle = xmalloc(sizeof(*myhandle));
 
    memcached_st *server = memcached_create(NULL);
    memcached_server_add (server, host, port);
 
    myhandle->server = server;
    myhandle->jsmemcached = obj;
    myhandle->cx = cx;
 
    JS_SetPrivate(cx, obj, myhandle);
 
    return JS_TRUE;
}
APE_JS_NATIVE(apememcached_sm_get)
//{
    JSString *query;
    struct _ape_memcached_data *myhandle;
    jsval callback;
 
    if ((myhandle = JS_GetPrivate(cx, obj)) == NULL) {
        return JS_TRUE;
    }
 
    if (!JS_ConvertArguments(cx, 1, argv, "S", &query)) {
        return JS_TRUE;
    }
 
    size_t value_length;
    uint32_t flags;
    memcached_return_t error;
 
    char *value = memcached_get(myhandle->server, JS_GetStringBytes(query), JS_GetStringLength(query), &value_length, &flags, &error);
 
    *rval = STRING_TO_JSVAL(JS_NewStringCopyN(cx, value, value_length));
 
    free(value);
 
    return JS_TRUE;
}

Finally, we need to link this together. You need to find function called “ape_sm_define_ape” and add this:

JSObject *jsmemcached;
jsmemcached = JS_InitClass(asc->cx, obj, NULL, &memcached_class, ape_sm_memcached_constructor, 2, NULL, NULL, NULL, apememcached_funcs_static);
JS_DefineFunctions(asc->cx, jsmemcached, apememcached_funcs);

In your javascript code, you can use the newly created class like this:

var cache = new Ape.Memcached("localhost", 11211);
cache.get('test');

Thats all, I’m sorry for the lack of explanation.

Original article - http://ziga.hamsworld.net/2010/04/27/ape-project-how-to-build-server-side-module-in-c-to-use-with-javascript/