使用native-c construstor从c构建新的DUKTAPE js对象

时间:2017-04-26 16:02:02

标签: duktape

我正在尝试在C中完全构建JS对象,类似于以下 JS

<?php
  if (is_page_template( 'page-show.php' ) ) {
      echo "$show_name - " . wp_title( '|', false, 'right' ) . " Leicester";
  } else {
      echo wp_title( '|', false, 'right' ) . ' Leicester';
  }
  ?>

将它用于NodeJS模块的事实很重要,因为A和B都不是全局可访问的。

为了做到这一点,我在 C

中写了以下模式
var _a = function(p){
    this.p = p;           
}

_a.prototype.myFunction= function(){ ...; }

var _b = function(){
   this.sub = new _a(p);
}

exports.A = A;
exports.B = B;

但正如我所怀疑的那样,在调用duk_new时没有正确设置a的原型,并且在 JS

中的任何尝试使用函数失败
duk_ret_t _js_a_dtor(duk_context *ctx) {
}

duk_ret_t _js_a_ctor(duk_context *ctx) {

    if (!duk_is_constructor_call(ctx)) {
        return DUK_RET_TYPE_ERROR;
    }

    // Push special this binding to the function being constructed
    duk_push_this(ctx);

    // Store the function destructor
    duk_push_c_function(ctx, _js_a_dtor, 0);
    duk_set_finalizer(ctx, -2);
    return 0;
}

duk_ret_t _js_a_myFunction(duk_context *ctx) {
...
}

static const duk_function_list_entry _js_a_funcs[] = {
    { "", _js_a_myFunction, 0 },
    { NULL, NULL, 0 }
};


duk_ret_t _js_b_dtor(duk_context *ctx) {
}

duk_ret_t _js_b_ctor(duk_context *ctx) {

    if (!duk_is_constructor_call(ctx)) {
        return DUK_RET_TYPE_ERROR;
    }

    // Push special this binding to the function being constructed
    duk_push_this(ctx);

    duk_push_c_function(ctx, _js_a_ctor, 0);
    duk_new(ctx,0);
    duk_put_prop_string(ctx,"sub");

    // Store the function destructor
    duk_push_c_function(ctx, _js_b_dtor, 0);
    duk_set_finalizer(ctx, -2);
    return 0;
}

void duk_init_class(duk_context *ctx, void * ctor, int paramsCount, duk_function_list_entry * func, char * className)
{
    // Create object function
    duk_push_c_function(ctx, ctor, paramsCount);       // [{exports},{ctor}]

    // Create a prototype with all functions
    duk_push_object(ctx);                              // [{exports}, { ctor }, {}]
    duk_put_function_list(ctx, -1, func);              // [{exports}, { ctor }, {}]
    duk_put_prop_string(ctx, -2, DUK_PROTOTYPE_NAME);  // [{exports}, { ctor }]

    // Now store the object function
    duk_put_prop_string(ctx, -2, className);           // [{exports}]
}

关于如何解决这个问题的任何想法? 我已经知道我可以将构造函数放在全局中,但我想如果有另一个直接替代方法将原型与c函数绑定...

问候。

1 个答案:

答案 0 :(得分:1)

Duktape / C函数默认没有.prototype属性,所以当它们被称为构造函数时,创建的实例将继承自Object.prototype。要更改它,您只需设置函数的.prototype属性。

因此,如果我理解正确,在您的情况下,您可以执行以下操作:

/* Build prototype object, here: { myFunction: ... } */
duk_push_object(ctx);
duk_push_c_function(ctx, _js_a_myFunction, ...);
duk_put_prop_string(ctx, -2, "myFunction");

/* Set A.prototype. */
duk_put_prop_string(ctx, idx_for_A_ctor, "prototype");

如果您正在使用duk_put_function_list(),则需要从目标对象中读取构造函数值,以便设置其.prototype