topbanner_forum
  *

avatar image

Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
  • Friday December 13, 2024, 4:45 am
  • Proudly celebrating 15+ years online.
  • Donate now to become a lifetime supporting member of the site and get a non-expiring license key for all of our programs.
  • donate

Author Topic: Duktape/Dukglue: Embed JavaScript in your application without blowing it up!  (Read 4973 times)

Tuxman

  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 2,508
    • View Profile
    • Donate to Member
While reviewing small browsers, I came across NetSurf as well. NetSurf is a fast and bloat-free web browser which happens to have got JavaScript support in younger incarnations by adding the Duktape ECMAScript engine.

Duktape, written in C, is much smaller than V8 or similar JS engines, making it a good choice for embedded systems or things like adding a scripting functionality to existing software. No web browser involved! It supports ECMAScript 5.1 with some additions from newer revisions, including regular expressions and Unicode. For lazy people like me, there is a C++ wrapper named Dukglue (quack!) available which lacks (good) documentation but works like a charm. If you ever thought that your application could need a good scripting engine, Duktape seems to be a good choice. Your C/C++ code can access any script functions and your scripts can access exported C/C++ symbols which is easier than it sounds.

You want an example? You get an example!
Assume that you want to have a JavaScript plug-in which doubles any input value.

Code: Javascript [Select]
  1. var DemoScript = {};
  2. DemoScript.double = function(number) {
  3.     return number*2;
  4. }
  5. DemoScript;

Here's how Dukglue probably* handles it:

Code: C++ [Select]
  1. #include <string>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <dukglue/dukglue.h> // <- this is important
  5.  
  6. // ... blah ...
  7.  
  8. void processScripts(scriptfile) {
  9.     duk_context* ctx = duk_create_heap_default();
  10.    
  11.     std::ifstream infile(scriptfile); // add the exists() check yourself pls.
  12.     std::string file_contents = [&infile] {
  13.         // Read the script file contents for processing.
  14.         std::ostringstream ss{};
  15.         ss << infile.rdbuf();
  16.         return ss.str();
  17.     }();
  18.  
  19.     try {
  20.         // Give me a local handle to the script:
  21.         DukValue script = dukglue_peval<DukValue>(ctx, file_contents.c_str());
  22.  
  23.         // Try to call double(2):
  24.         int value = dukglue_pcall_method<int>(ctx, script, "double", 2);
  25.         std::cout << "The double value of 2 is " << value << std::endl;
  26.     }
  27.     catch (DukException& e) {
  28.         // Damn.
  29.         std::cout << "Blimey! Something bad happened. " << e.what();
  30.     }
  31.    
  32.     duk_destroy_heap(ctx);
  33. }
  34.  
  35. // now call processScripts("double.js"); or whatever.

* I was lazy, I just assumed it would work like this and it probably does. A more complex and actually tested ;) example is part of my blog software (nudge, nudge).

According to mouser, this might be interesting for more people than just me. So here it is. :)
« Last Edit: November 23, 2017, 05:24 AM by Tuxman, Reason: removed unnecessary include »

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 40,914
    • View Profile
    • Mouser's Software Zone on DonationCoder.com
    • Read more about this member.
    • Donate to Member
Neat. That could be useful for us c++ coders. Thanks for sharing that  :up: