使用 native-c 构造器从 c 构建新的 DUKTAPE js 对象
build new DUKTAPE js object from c with native-c construstor
我正在尝试完全用 C 构建 JS 对象,类似于以下 JS:
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;
将它用于 NodeJS 模块这一事实很重要,因为 A 和 B 都不是全局可访问的。
为了做到这一点,我在 C 中编写了以下模式:
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}]
}
但正如我所怀疑的那样,在调用 duk_new 时未正确设置 a 的原型,并且在 JS[= 中任何尝试在 a 上使用函数都失败了13=]
var m = require('mymodule');
var a = new m.A(); // working
a.myFunction(); // working
var b = new m.B(); // working
b.sub ; // defined
b.sub.myFunction(); // failed while myFunction is undefined..
知道如何解决这个问题吗??
我已经知道我可以将构造函数放在全局中,但我想是否有另一种直接替代方法可以将原型与 c 函数绑定...
此致。
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
.
我正在尝试完全用 C 构建 JS 对象,类似于以下 JS:
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;
将它用于 NodeJS 模块这一事实很重要,因为 A 和 B 都不是全局可访问的。
为了做到这一点,我在 C 中编写了以下模式:
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}]
}
但正如我所怀疑的那样,在调用 duk_new 时未正确设置 a 的原型,并且在 JS[= 中任何尝试在 a 上使用函数都失败了13=]
var m = require('mymodule');
var a = new m.A(); // working
a.myFunction(); // working
var b = new m.B(); // working
b.sub ; // defined
b.sub.myFunction(); // failed while myFunction is undefined..
知道如何解决这个问题吗?? 我已经知道我可以将构造函数放在全局中,但我想是否有另一种直接替代方法可以将原型与 c 函数绑定...
此致。
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
.