2015-05-18 3 views
8

कहते हैं कि मैं एक C++ वर्ग प्वाइंटनिर्यात C++ वर्ग duktape को

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

    float X; 
    float Y; 

}; 

है मैं यह करने के लिए जावास्क्रिप्ट कार्यक्षमता जोड़ने और duktape चुना है करना चाहते हैं।

यह जावास्क्रिप्ट में इस वर्ग के पुन: उपयोग करने के लिए संभव है? कहना

var p = new Point(1.23, 4.56); 

मैं duktape प्रलेखन पढ रहा हूं और यह केवल कहते हैं जावास्क्रिप्ट अंदर कार्यों का पुन: उपयोग करने के लिए कैसे।

उत्तर

10

मेरा व्यक्तिगत सलाह के लिए यह सिर्फ आप जावास्क्रिप्ट में करना होगा चाहते सी ++ बाइंडिंग तैयार करना है।

जावास्क्रिप्ट ऑब्जेक्ट में वास्तविक सी ++ ऑब्जेक्ट को सहेजने की एकमात्र आवश्यकता है, हम उस उद्देश्य के लिए internal properties का उपयोग करते हैं।

आप एक समारोह है कि एक निर्माता समारोह के रूप में जावास्क्रिप्ट से बुलाया जाएगा बनाने की जरूरत है, तो आप सिर्फ अपने प्रोटोटाइप को भरने और एक finalizer सेट करना होगा। यह मुश्किल नहीं है लेकिन इसके लिए बहुत सारे कोड की आवश्यकता है ताकि आप मूल रूप से उन्हें आसान बनाने के लिए रैपर बनाना चाहते हैं।

#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

आप \ xff \ xffdata का उपयोग क्यों करते हैं - क्या यह जावास्क्रिप्ट से संपत्ति को छिपाने के लिए है? साथ ही, आपको हटाई गई संपत्ति की आवश्यकता क्यों है - क्या आप डेटा प्रॉपर्टी को नलप्टर पर सेट नहीं कर सकते हैं और इसका उपयोग कर सकते हैं? – imekon

+0

आह ... बस आंतरिक गुण दस्तावेज़ पढ़ें - इसलिए \ xff \ – imekon

+0

xff हाँ बिल्कुल, मैं माफी मैं इसे समझाने के लिए भूल गया हूँ। – markand

संबंधित मुद्दे