Top |
#define | CHECK_ARG_COUNT() |
#define | DEFINE_ENUM_MEMBER() |
#define | DEFINE_ENUM_MEMBER_EXT() |
SeedObject | (*SeedModuleInitCallback) () |
Seed includes a simple system for creating C modules which can be loaded and manipulated from JavaScript. This is used for implementing performance-critical code closer to the silicon, as well as binding non-introspectable libraries in an attractive way.
Numerous binding modules are included in the Seed repository; when writing a new native module, it would be wise to look over these before beginning, as they have many tidbits of useful knowledge for writing modules.
Example 11. Very simple example C module
1 2 3 4 5 6 7 8 9 10 |
#include <glib.h> #include <seed-module.h> SeedObject seed_module_init(SeedEngine * eng) { /* Say hello! */ g_print("Hello, Seed Module World!\n"); /* Return an empty object as the module's namespace */ return seed_make_object (eng->context, NULL, NULL); } |
Above is a C module which does absolutely nothing useful. When a module is loaded, seed_module_init()
is called, which should have the signature of SeedModuleInitCallback()
. You're passed the global SeedEngine, and the value you return is the namespace for your module. Say, for example, you place a static function on that object:
Example 12. C module with a function
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#include <glib.h> #include <seed-module.h> /* Our function, with the signature of SeedFunctionCallback(); say hello! */ SeedValue say_hello_to(SeedContext ctx, SeedObject function, SeedObject this_object, gsize argument_count, const SeedValue arguments[], SeedException *exception) { guchar * name; /* Check that only one argument was passed into the function. CHECK_ARG_COUNT() is from seed-module.h, which you might find useful. */ CHECK_ARG_COUNT("hello.say_hello_to", 1); /* Convert the first argument, a <a class="link" href="seed-Native-Type-Conversion.html#SeedValue" title="SeedValue">SeedValue</a>, to a C string */ name = seed_value_to_string(ctx, arguments[0], exception); g_print("Hello, %s!\n", name); g_free(name); return seed_make_null(ctx); } /* Define an array of <GTKDOCLINK HREF="seed-static-function">seed_static_function</GTKDOCLINK> */ seed_static_function gettext_funcs[] = { {"say_hello_to", say_hello_to, 0} }; SeedObject seed_module_init(SeedEngine * eng) { SeedGlobalContext ctx = eng->context; /* Create a new class definition with our array of static functions */ seed_class_definition ns_class_def = seed_empty_class; ns_class_def.static_functions = example_funcs; /* Create a class from the class definition we just created */ SeedClass ns_class = seed_create_class(&ns_class_def); /* Instantiate the class; this instance will be the namespace we return */ ns_ref = seed_make_object (ctx, ns_class, NULL); seed_value_protect (ctx, ns_ref); return ns_ref; } |
After building and installing this module (look in the Seed build system for examples of how to get this to work, as well as a copy of seed-module.h, which will be very useful), it will be loadable with the normal Seed import system. Assuming it's installed as libseed_hello.so:
Example 13. Utilize our second example C module from JavaScript
1 2 |
hello = imports.hello; hello.say_hello_to("Tim"); |
#define CHECK_ARG_COUNT(name, argnum)
Check that the required number of arguments were passed into a
SeedFunctionCallback. If this is not true, raise an exception and
return NULL
. This requires the callback to use "argument_count",
"ctx", and "exception" as the names of the various function arguments.
name
should be of form "namespace.function_name"
At the moment, there is no way to specify more than one acceptable argument count.
#define DEFINE_ENUM_MEMBER(holder, member)
Defines a property on holder
which is named the same as member
, and
is assigned the value that member
has in C.
This macro works for defining properties from constants and #defines as well.
#define DEFINE_ENUM_MEMBER_EXT(holder, name, val)
Defines a property on holder
which is named name
, and is assigned the
value that member
has in C. This allows for an override of the enum
member's name, most often to remove a common prefix. For example, to declare
a property named VERSION_MAJOR on the namespace from mfpr's version
constant MPFR_VERSION_MAJOR:
DEFINE_ENUM_MEMBER_EXT(ns, "VERSION_MAJOR", MPFR_VERSION_MAJOR);