Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript extension to use C based APIs(clutter) in a webapp

My goal is to use the C libraries to form web apps.

I have chosen the way to do that via using "SWIG" tool. The Swig tool requires three things:

  1. .c file which defines all the functions.

  2. .i file also called interface file which is creating the interface to load the APIs wherein I used the extern keyword.

  3. APP written in Javascript extension (.js file).

I used SWIG tool to compile and run this app to verify the .js file has made correctly. The application is running fine on XMING X11 window.

On compilation it creates _wrap.o, .o file and libFILENAME.so.

Now I want to run this app on browser page.

For this I have used the webkit clutter port which gives us the MxLauncher code. I'm using webkit_iweb_view_load_uri(WEBKIT_IWEB_VIEW(view), "filename.html"); API to load my html file to run that Javascript on my webpage view.

I'm linking the .so created at the compilation time.

Error Message: JS CONSOLE: file:///filename.js: ReferenceError: Can't find variable: example

filename.c

int gcd(int x, int y) `enter code here`{
  int g;
  g = y;
  while (x > 0) {
    g = x;
    x = y % x;
    y = g;
  }
  return g;
}

filename.i

%module example
extern int    gcd(int x, int y);

filename.js

x = 42;
y = 105;
g = example.gcd(x,y);

How to get my goal to be achieved?

like image 230
user1872227 Avatar asked Dec 03 '12 10:12

user1872227


1 Answers

You also need to tell WebKit/JavaScriptCore at runtime about your bindings (this is in addition to linking with filename_wrap.o).

Specifically you need to bind them to the global JavaScript object (in order to invoke per your .js examples). A callback on the WebKit window can be used to get a timely reference to the global JavaScript context, and then you can register your functions onto it.

Adapting this example of hooking into the window-object-cleared signal the code could look similar to this:

/* the window callback - 
     fired when the JavaScript window object has been cleared */
static void window_object_cleared_cb(WebKitWebView  *web_view,
                                     WebKitWebFrame *frame,
                                     gpointer        context,
                                     gpointer        window_object,
                                     gpointer        user_data)
{
  /* Add your classes to JavaScriptCore */
  example_init(context); // example_init generated by SWIG
}


/* ... and in your main application set up */
void yourmainfunc()
{
    ....

    g_signal_connect (G_OBJECT (web_view), "window-object-cleared",
        G_CALLBACK(window_object_cleared_cb), web_view);

    webkit_web_view_load_uri (WEBKIT_WEB_VIEW (web_view), "file://filename.html");

    ...
}

Depending on which branch of SWIG you are using you may need to generate the example_init function yourself (check filename.cxx); for reference here is what an initializer function to register wrapped C functions would look like in SWIG:

int example_init(JSContextRef context) {
  JSObjectRef global = JSContextGetGlobalObject(context);
 ...
  jsc_registerFunction(context, global,  "gcd", _wrap_gcd);
 ...
}

NOTE -- SWIG does not yet officially support JavaScript; the above refers to using the work-in-progress (non-production) SWIG branches.

References:

  • SWIG-V8 source and its Javascript documentation
  • swig-jsc source and its example of registering bindings
  • SWIG JavaScriptCore GSoC project source (Google Summer of Code 2012)
  • Webkit: Extending JavaScript article-- tutorial / example code
like image 198
humbletim Avatar answered Sep 19 '22 17:09

humbletim