gpt4 book ai didi

javascript - 将 C++ 类导出到 duktape

转载 作者:可可西里 更新时间:2023-11-01 17:37:59 25 4
gpt4 key购买 nike

假设我有一个 C++ 类 Point

class Point {
public:
Point();
Point(float x, float y);
~Point();

float X;
float Y;

};

我想为其添加 javascript 功能并选择了 duktape。

是否可以在 javascript 中重用此类?说

var p = new Point(1.23, 4.56);

我一直在阅读 duktape 文档,它只说明了如何在 javascript 中重用函数。

最佳答案

我个人的建议是像在 JavaScript 中那样为它创建 C++ 绑定(bind)。

唯一需要的,就是在JavaScript对象中保存真正的C++对象,我们使用internal properties为此目的。

您需要创建一个将作为构造函数从 JavaScript 调用的函数,然后您只需填充其原型(prototype)并设置终结器即可。这并不难,但需要大量代码,因此您基本上想要创建包装器以简化它们。

#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;
}

关于javascript - 将 C++ 类导出到 duktape,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30296953/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com