2015-05-18 3 views
8

sagen, ich habe eine C++ class PointExport C++ Klasse duktape

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

    float X; 
    float Y; 

}; 

ich JavaScript-Funktionalität, um es hinzufügen möchten und wählen duktape.

ist es möglich, diese Klasse in Javascript wieder zu verwenden? sagen

var p = new Point(1.23, 4.56); 

Ich habe die duktape Dokumentation gelesen, und es sagt nur, wie Funktionen in Javascript wiederzuverwenden.

Antwort

10

Mein persönlicher Rat ist es, C++ - Bindungen zu erstellen, genau wie in JavaScript.

Die einzige Notwendigkeit, das reale C++ - Objekt im JavaScript-Objekt zu speichern, verwenden wir internal properties für diesen Zweck.

Sie müssen eine Funktion erstellen, die von JavaScript als Konstruktorfunktion aufgerufen wird, dann müssen Sie nur ihren Prototyp ausfüllen und einen Finalizer setzen. Es ist nicht schwer, aber es erfordert viel Code, so dass Sie im Grunde Wrapper erstellen möchten, um sie einfacher zu machen.

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

Warum verwenden Sie \ xff \ xffdata - ist das die Eigenschaft aus Javascript zu verbergen? Warum brauchen Sie auch eine gelöschte Eigenschaft - könnten Sie die Dateneigenschaft nicht auf nullptr setzen und diese verwenden? – imekon

+0

Ah ... lesen Sie einfach die Dokumentation der internen Eigenschaften - daher die \ xff \ xff – imekon

+0

Ja genau, es tut mir leid, dass ich vergessen habe, es zu erklären. – markand