出口c&x2B+;类到duktape 我个人的建议是,为它创建C++绑定,就像您在JavaScript中所做的那样。 唯一的需要,是在JavaScript对象中保存真正的C++对象,我们为此目的使用。

出口c&x2B+;类到duktape 我个人的建议是,为它创建C++绑定,就像您在JavaScript中所做的那样。 唯一的需要,是在JavaScript对象中保存真正的C++对象,我们为此目的使用。,javascript,c++,duktape,Javascript,C++,Duktape,我想向它添加javascript功能,并选择duktape 可以在javascript中重用这个类吗? 说 我一直在阅读Duk磁带文档,它只讲述如何在JavaScript中重用函数。 < P>我个人的建议是,为它创建C++绑定,就像您在JavaScript中所做的那样。 唯一的需要,是在JavaScript对象中保存真正的C++对象,我们为此目的使用。 您需要创建一个将从JavaScript作为构造函数调用的函数,然后只需填充其原型并设置终结器。这并不难,但它需要很多代码,所以您基本上希望创建包

我想向它添加javascript功能,并选择duktape

可以在javascript中重用这个类吗? 说


我一直在阅读Duk磁带文档,它只讲述如何在JavaScript中重用函数。

< P>我个人的建议是,为它创建C++绑定,就像您在JavaScript中所做的那样。

唯一的需要,是在JavaScript对象中保存真正的C++对象,我们为此目的使用。 您需要创建一个将从JavaScript作为构造函数调用的函数,然后只需填充其原型并设置终结器。这并不难,但它需要很多代码,所以您基本上希望创建包装器以使它们更容易

#include <iostream>

#include "duktape.h"

class Point {
public:
    float x;
    float y;
};

/*
 * This is the point destructor
 */
duk_ret_t js_Point_dtor(duk_context *ctx)
{
    // The object to delete is passed as first argument instead
    duk_get_prop_string(ctx, 0, "\xff""\xff""deleted");

    bool deleted = duk_to_boolean(ctx, -1);
    duk_pop(ctx);

    if (!deleted) {
        duk_get_prop_string(ctx, 0, "\xff""\xff""data");
        delete static_cast<Point *>(duk_to_pointer(ctx, -1));
        duk_pop(ctx);

        // Mark as deleted
        duk_push_boolean(ctx, true);
        duk_put_prop_string(ctx, 0, "\xff""\xff""deleted");
    }

    return 0;
}

/*
 * This is Point function, constructor. Note that it can be called
 * as a standard function call, you may need to check for
 * duk_is_constructor_call to be sure that it is constructed
 * as a "new" statement.
 */
duk_ret_t js_Point_ctor(duk_context *ctx)
{
    // Get arguments
    float x = duk_require_number(ctx, 0);
    float y = duk_require_number(ctx, 1);

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

    // Store the underlying object
    duk_push_pointer(ctx, new Point{x, y});
    duk_put_prop_string(ctx, -2, "\xff""\xff""data");

    // Store a boolean flag to mark the object as deleted because the destructor may be called several times
    duk_push_boolean(ctx, false);
    duk_put_prop_string(ctx, -2, "\xff""\xff""deleted");

    // Store the function destructor
    duk_push_c_function(ctx, js_Point_dtor, 1);
    duk_set_finalizer(ctx, -2);

    return 0;
}

/*
 * Basic toString method
 */
duk_ret_t js_Point_toString(duk_context *ctx)
{
    duk_push_this(ctx);
    duk_get_prop_string(ctx, -1, "\xff""\xff""data");
    Point *point = static_cast<Point *>(duk_to_pointer(ctx, -1));
    duk_pop(ctx);
    duk_push_sprintf(ctx, "%f, %f", point->x, point->y);

    return 1;
}

// methods, add more here
const duk_function_list_entry methods[] = {
    { "toString",   js_Point_toString,  0   },
    { nullptr,  nullptr,        0   }
};

int main(void)
{
    duk_context *ctx = duk_create_heap_default();

    // Create Point function
    duk_push_c_function(ctx, js_Point_ctor, 2);

    // Create a prototype with toString and all other functions
    duk_push_object(ctx);
    duk_put_function_list(ctx, -1, methods);
    duk_put_prop_string(ctx, -2, "prototype");

    // Now store the Point function as a global
    duk_put_global_string(ctx, "Point");

    if (duk_peval_string(ctx, "p = new Point(20, 40); print(p)") != 0) {
        std::cerr << "error: " << duk_to_string(ctx, -1) << std::endl;
        std::exit(1);
    }

    return 0;
}
#包括
#包括“duktape.h”
类点{
公众:
浮动x;
浮动y;
};
/*
*这是点析构函数
*/
duk_ret_t js_Point_dtor(duk_context*ctx)
{
//要删除的对象作为第一个参数传递
duk_get_prop_字符串(ctx,0,“\xff”“\xff”“已删除”);
bool deleted=duk_to_boolean(ctx,-1);
杜库普(ctx);
如果(!已删除){
duk_get_prop_字符串(ctx,0,“\xff”“\xff”“数据”);
删除静态_转换(duk_to_指针(ctx,-1));
杜库普(ctx);
//标记为已删除
duk_push_boolean(ctx,true);
duk_put_prop_string(ctx,0,“\xff”“\xff”“已删除”);
}
返回0;
}
/*
*这是点函数,构造函数。注意,它可以被称为
*作为标准函数调用,您可能需要检查
*duk_是_构造函数_调用,以确保它已构造
*作为“新”的声明。
*/
duk_ret_t js_Point_ctor(duk_context*ctx)
{
//获取参数
浮点数x=duk_要求_编号(ctx,0);
浮动y=duk_要求_编号(ctx,1);
//将此绑定推送到正在构造的函数
duk_push_this(ctx);
//存储底层对象
duk_push_指针(ctx,新点{x,y});
duk_put_prop_字符串(ctx,-2,“\xff”“\xff”“数据”);
//存储布尔标志以将对象标记为已删除,因为析构函数可能会被调用多次
duk_push_布尔值(ctx,false);
duk_put_prop_string(ctx,-2,“\xff”“\xff”“删除”);
//存储函数析构函数
duk_push_c_函数(ctx,js_Point_dtor,1);
duk_集_终结器(ctx,-2);
返回0;
}
/*
*基本toString方法
*/
duk_ret_t js_Point_toString(duk_context*ctx)
{
duk_push_this(ctx);
duk_get_prop_字符串(ctx,-1,“\xff”“\xff”“数据”);
点*点=静态_转换(duk_到_指针(ctx,-1));
杜库普(ctx);
duk_push_sprintf(ctx,“%f,%f”,点->x,点->y);
返回1;
}
//方法,请在此处添加更多
常量duk_函数列表_输入方法[]={
{“toString”,js_Point_toString,0},
{nullptr,nullptr,0}
};
内部主(空)
{
duk_context*ctx=duk_create_heap_default();
//创建点函数
duk_push_c_函数(ctx,js_Point_ctor,2);
//使用toString和所有其他函数创建原型
duk_push_物体(ctx);
duk_put_函数列表(ctx,-1,方法);
duk_put_prop_string(ctx,-2,“原型”);
//现在将点函数存储为全局函数
duk_put_global_字符串(ctx,“点”);
如果(duk_peval_字符串(ctx,“p=新点(20,40);打印(p)”)!=0){

std::cerr为什么要使用\xff\xffdata?这是为了对Javascript隐藏属性吗?还有,为什么需要删除属性?您不能将数据属性设置为nullptr并使用它吗?啊…只需阅读内部属性文档-因此是\xff\xffy,很抱歉,我忘了解释它。关于重用是否将e\xff\xffdata属性的值重置为null,以此作为“标志”?
#include <iostream>

#include "duktape.h"

class Point {
public:
    float x;
    float y;
};

/*
 * This is the point destructor
 */
duk_ret_t js_Point_dtor(duk_context *ctx)
{
    // The object to delete is passed as first argument instead
    duk_get_prop_string(ctx, 0, "\xff""\xff""deleted");

    bool deleted = duk_to_boolean(ctx, -1);
    duk_pop(ctx);

    if (!deleted) {
        duk_get_prop_string(ctx, 0, "\xff""\xff""data");
        delete static_cast<Point *>(duk_to_pointer(ctx, -1));
        duk_pop(ctx);

        // Mark as deleted
        duk_push_boolean(ctx, true);
        duk_put_prop_string(ctx, 0, "\xff""\xff""deleted");
    }

    return 0;
}

/*
 * This is Point function, constructor. Note that it can be called
 * as a standard function call, you may need to check for
 * duk_is_constructor_call to be sure that it is constructed
 * as a "new" statement.
 */
duk_ret_t js_Point_ctor(duk_context *ctx)
{
    // Get arguments
    float x = duk_require_number(ctx, 0);
    float y = duk_require_number(ctx, 1);

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

    // Store the underlying object
    duk_push_pointer(ctx, new Point{x, y});
    duk_put_prop_string(ctx, -2, "\xff""\xff""data");

    // Store a boolean flag to mark the object as deleted because the destructor may be called several times
    duk_push_boolean(ctx, false);
    duk_put_prop_string(ctx, -2, "\xff""\xff""deleted");

    // Store the function destructor
    duk_push_c_function(ctx, js_Point_dtor, 1);
    duk_set_finalizer(ctx, -2);

    return 0;
}

/*
 * Basic toString method
 */
duk_ret_t js_Point_toString(duk_context *ctx)
{
    duk_push_this(ctx);
    duk_get_prop_string(ctx, -1, "\xff""\xff""data");
    Point *point = static_cast<Point *>(duk_to_pointer(ctx, -1));
    duk_pop(ctx);
    duk_push_sprintf(ctx, "%f, %f", point->x, point->y);

    return 1;
}

// methods, add more here
const duk_function_list_entry methods[] = {
    { "toString",   js_Point_toString,  0   },
    { nullptr,  nullptr,        0   }
};

int main(void)
{
    duk_context *ctx = duk_create_heap_default();

    // Create Point function
    duk_push_c_function(ctx, js_Point_ctor, 2);

    // Create a prototype with toString and all other functions
    duk_push_object(ctx);
    duk_put_function_list(ctx, -1, methods);
    duk_put_prop_string(ctx, -2, "prototype");

    // Now store the Point function as a global
    duk_put_global_string(ctx, "Point");

    if (duk_peval_string(ctx, "p = new Point(20, 40); print(p)") != 0) {
        std::cerr << "error: " << duk_to_string(ctx, -1) << std::endl;
        std::exit(1);
    }

    return 0;
}