Duktape ExampleAuthor: Dave Date: 06.07.15 - 6:53am Here is an small but interesting program that utilizes the duktape javascript engine. In the last post I was wondering how to handle a COM method which returned a live object instance, and how to have the methods on that sub object returned to the js environment and route calls from that specific instance back to that specific object. The below template demonstrates how to accomplish this. javascript executed: function testClass(){ this.hInst=0; this.ReadAll = function(){ print('testClass.ReadAll() called'); } } var ts = nativeFunc('file.txt'); print('ts=' + ts); print('ts.hInst = ' + ts.hInst); ts.ReadAll(); ts=null; print('test complete'); C program: //ref: http://stackoverflow.com/questions/30296953/export-c-class-to-duktape #include "./duk/duktape.h" #include <conio.h> /* output: nativefunc(file.txt) returning a new testClass instance ts=[object Object] ts.hInst = 12345 testClass.ReadAll() called textstream instance 12345 released! test complete */ duk_ret_t js_testClass_dtor(duk_context *ctx) { int hInst = 0; // The object to delete is passed as first argument //retrieve this.hInst numeric value duk_get_prop_string(ctx, 0, "hInst"); hInst = duk_to_number(ctx, -1); duk_pop(ctx); printf("textstream instance %d released!\n", hInst); return 0; } int nativeFunc(duk_context *ctx) { int i; const char* arg0 = 0; //int n = duk_get_top(ctx); //arg count arg0 = duk_safe_to_string(ctx, 0); printf("nativefunc(%s) returning a new testClass instance\n", arg0); //create a new testClass javascript object instance duk_get_global_string(ctx, "testClass"); duk_new(ctx, 0); //set this.hInst = 12345 duk_push_number(ctx, 12345); duk_put_prop_string(ctx, -2, "hInst"); //register a C function to run when js obj released duk_push_c_function(ctx, js_testClass_dtor, 1); duk_set_finalizer(ctx, -2); return 1; } int main(int argc, char *argv[]) { duk_context *ctx = duk_create_heap_default(); char* mClass = "function testClass(){\n" " this.hInst=0;\n" " this.ReadAll = function(){\n" " print('testClass.ReadAll() called');\n" " }\n" "}"; //add this script fragment to the current context (used latter) //safe to call eval to avoid fatal panic handler on syntax error duk_push_string(ctx, mClass); if (duk_peval(ctx) != 0) { printf("eval failed: %s\n", duk_safe_to_string(ctx, -1)); goto finished; } //register a new native function for use in JS duk_push_global_object(ctx); duk_push_c_function(ctx, nativeFunc, DUK_VARARGS); duk_put_prop_string(ctx, -2, "nativeFunc"); duk_pop(ctx); char* test = "var ts = nativeFunc('file.txt');\n" "print('ts=' + ts);\n" "print('ts.hInst = ' + ts.hInst);\n" "ts.ReadAll();\n" "ts=null;\n" "print('test complete');"; //now we will run a block of JS in configured envirnoment.. duk_push_string(ctx, test); if (duk_peval(ctx) != 0) { printf("eval failed: %s\n", duk_safe_to_string(ctx, -1)); } duk_pop(ctx); finished: duk_destroy_heap(ctx); getch(); return 0; } Comments: (0) |
About Me More Blogs Main Site |