DonationCoder.com forum
 
Read-only archive. This is a static copy of the DonationCoder.com forum. Reading and searching work as before; logging in, posting and private messages do not.
Archive of 2026-10-21 · About this archive · Main site

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

Tuxman

  • OMG not him again!
  • Supporting Member
  • Joined in 2006
  • **
  • Posts: 2,522
    • Participated in NANY Challenge Seven Times
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)
var DemoScript = {};
DemoScript.double = function(number) {
    return number*2;
}
DemoScript;

Here's how Dukglue probably* handles it:

Code: ( cpp)
#include <string>
#include <iostream>
#include <fstream>
#include <dukglue/dukglue.h> // <- this is important

// ... blah ...

void processScripts(scriptfile) {
    duk_context* ctx = duk_create_heap_default();
    
    std::ifstream infile(scriptfile); // add the exists() check yourself pls.
    std::string file_contents = [&infile] {
        // Read the script file contents for processing.
        std::ostringstream ss{};
        ss << infile.rdbuf();
        return ss.str();
    }();

    try {
        // Give me a local handle to the script:
        DukValue script = dukglue_peval<DukValue>(ctx, file_contents.c_str());

        // Try to call double(2):
        int value = dukglue_pcall_method<int>(ctx, script, "double", 2);
        std::cout << "The double value of 2 is " << value << std::endl;
    }
    catch (DukException& e) {
        // Damn.
        std::cout << "Blimey! Something bad happened. " << e.what();
    }
    
    duk_destroy_heap(ctx);
}

// 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. :)
I bet when Cheetahs race and one of them cheats, the other one goes "Man, you're such a Cheetah!" and they laugh & eat a zebra or whatever.
« Last Edit: November 23, 2017, 11:24 AM by Tuxman »

mouser

  • First Author
  • Administrator
  • Joined in 2005
  • *****
  • Posts: 40,931
    • Gathering Badge
    • Plugin Coding Medal
    • Participated in NANY Challenge Seventeen Times
    • Cody Award
    • Coding Snacks
    • Volunteers/Staff
Neat. That could be useful for us c++ coders. Thanks for sharing that  :up:

Original address: https://www.donationcoder.com/forum/index.php?topic=44293.0