![]() |
![]() |
![]() |
Seed Reference Manual | ![]() |
---|---|---|---|---|
Top | Description |
#include <seed/seed.h> #define CHECK_ARG_COUNT (name, argnum) #define DEFINE_ENUM_MEMBER (holder, member) #define DEFINE_ENUM_MEMBER_EXT (holder, name, val) SeedObject (*SeedModuleInitCallback) (SeedEngine *eng);
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
#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
#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 SeedValue, 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 seed_static_function */ 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
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.
|
The name of the function being called from, pretty-printed |
|
The number of arguments which should be passed into the function |
#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.
|
The object on which to define the enum member |
|
The enum member, as it is named in C |
#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);
|
The object on which to define the enum member |
|
The enum member, as it should be named in JavaScript |
|
The enum member, as it is named in C |