Previous: , Up: Anatomy of a Emodule   [Contents][Index]


2.4 Loading other Emodules

Sometimes it is necessary to use functions, or generally symbols, defined in a foreign emodule you depend on. In general it is impossible to open (as in dlopen()) your emodule to extract the dependencies variable when you refer to one of these external symbols in your code. The corresponding error message goes along the lines of

Cannot open modules foo: Undefined symbol bar.

So what happened?

The emodule itself can contain dynamic references to other libraries, or, most likely, symbols from the SXEmacs binary. However, they have to be resolvable, and in fact are tried to be resolved, when opening a module. Now if you refer to symbols defined in another emodule 1 you, the user, have to load that other emodule before.

So what’s the rant about that dependencies thingiedingie?

As mentioned above the new load-module function will exactly relieve you, the user, of this task provided the emodule proclaimed the list of its dependencies. Now this seems to be a charade, in order to open the emodule to read its dependencies you, the user, have to load all of its dependencies because naively opening the emodule will yield nothing but the error above when foreign symbols are used.

The solution is to provide a, sort of, low-quality draught version of the foreign functions you, the emodule author, refer to. The missing link here are the so-called weak symbols. They usually do not carry any real information (variable) or functionality (function) and are meant to be overwritten by the “real” symbol as soon as possible. When properly coded their life-time spans just about the time from opening the emodule to opening the requisite module which, hopefully, defines real symbol and thence replaces the weak one.

Imagine ‘module-A’ is doing all the hard work and provides the function

/* inside module-A.c */
bool solve_complex_problem(void)
{
        …
        return true;
}

Now ‘module-B’ contains a function void compute_lotto_numbers(void) which goes:

/* inside module-B.c */
void compute_lotto_numbers(void)
{
        if (solve_complex_problem()) {
                /* lotto numbers found, hooray! print them */
                …
        }
        …
}

Leaving it like that will effectively bar your users from computing the lotto numbers and I personally would hate you, the emodule developer, for the rest of my life. However, to finish this example using weak symbols you would additionally put into module-B.c:

bool solve_complex_problem(void) __attribute__((weak));

bool solve_complex_problem(void)
{
        return false;
}

Some practical hints:


Footnotes

(1)

This was not possible with the old emodule system


Previous: , Up: Anatomy of a Emodule   [Contents][Index]