2010-06-18 13 views
29

Wydaje się, że official examples wystawiania klasy Punkt zakłada, że ​​w twoim programie będzie stała liczba jego wystąpień. Nie jest jasne, w jaki sposób nowe instancje są przydzielane w kodzie C++, kiedy nowy jest wywoływany w JavaScript.W jaki sposób udostępniasz klasę C++ w silniku JavaScript V8, aby można go było utworzyć za pomocą nowego?

W jaki sposób można wystawić klasę, która może mieć wiele wystąpień? Na przykład, klasa Obrazek:

var img1 = new Image(640, 480); 
var img2 = new Image(1024, 768); 

img1.clear("red"); 
img2.clear("black"); 

Odpowiedz

-11

nie wiem jak to osiągnąć w silniku V8 Js dokładnie, ale w świecie Pythona, można po prostu zrobić w następujący sposób. klasa Obrazek:

class Image 
{ 
public: 
    Image(int w, int h); 
    int Width(void) const; 
}; 

napisać niektóre funkcje opakowania i narazić te funkcje do świata JS:

Image* Image_New(int w, int h) { return new Image(w, h); } 
void Image_Delete(Image* pImage) { delete pImage; } 
int Image_Width(const Image* pImage) { return pImage->Width(); } 

dodać następujące kody do pliku JS:

var Image = function (w, h) { 
    this.image = new Image(w, h); 
    this.Width = function() { 
     return Image_Width(this.image); 
    }; 
}; 

i teraz możesz dostać pracę z kodem. Ponadto powyższe kody nie uwzględniają mechanizmu zbierania śmieci, dlatego warto zwrócić na to szczególną uwagę. Słyszałem moją angielszczyznę borken!

+0

Co z eksportowaniem zdefiniowanych funkcji? – Basilevs

+1

Tak, python ma świetne API do tego. Właśnie dlatego V8 jest tak zagmatwany! Dlaczego nie ma V8 :: FunctionTemplate :: SetClassAllocator (AllocateFn, FreeFn)? –

+2

v8 jest o wiele szybszy niż python choć – ShrekOverflow

30

To jest najlepsze blog post I could find on exposing C++ objects to V8 Javascript. Wchodzi w głębsze szczegóły i dzieli je na mniejsze kroki z fragmentami kodu. Ostrzegam: fragmenty kodu mają małe niespójności i zrozumienie zajęło mi kilka odczytów. Przeczytanie mojego krótkiego podsumowania z wyprzedzeniem może pomóc:

  1. Obiekty muszą być zawijane w szablony V8. Uwaga: w przykładzie Google użyto ObjectTemplates, ale autor wyjaśnia, dlaczego preferuje FunctionTemplates.
    1. Utwórz FunctionTemplate. Instancje tego szablonu mają wewnętrzne pole do przechowywania adresu pamięci obiektu C++. Dostają również metody klasy "accessor".
    2. Utwórz funkcję wrapObject(), która będzie owijać obiekt C++ w jednym z tych elementów FunctionTemplates.
  2. Konstruktor musi być również owinięty w (inny) szablon V8. Do uniknięcia niechcianej rekursji używany jest inny szablon. (Metoda łączenia obu szablonów w jeden jest opisana na końcu wpisu na blogu.)
    1. Utwórz kolejną funkcję FunctionTemplate. Ten szablon po prostu łączy globalny zakres JavaScript (z którego będzie wywoływany new) do konstruktora C++.
    2. Utwórz metodę, którą szablon wywoła. Ta metoda faktycznie używa operatora C++ new i wywołuje konstruktor klasy C++. Następnie opakowuje obiekt, wywołując metodę wrapObject() utworzoną w kroku 1.2.

Teraz pamięć alokowana w punkcie 2.2 musi być delete byłyby trochę czasu.Aktualizacja: Następny wpis na blogu, "Persistent Handles", opisuje to szczegółowo.

Moje notatki na actual code alluded to in these blog posts:

  • Sposób na blogu wrapPoint() faktycznie analogiczny do sposobu w rzeczywistym kodzie unwrap(); niewrap()
  • Aby znaleźć inne punkty wspólne między kodem, szukaj: SetInternalFieldCount(0, constructorCall
  • Rzeczywisty kod wydaje się zrobić zarządzanie pamięcią przy użyciu metody MakeWeak(), aby ustawić metodę wywołania zwrotnego, który robi porządki.
+0

wpis na blogu, który łączyłeś na górze, jest martwy – xaxxon

+0

@xaxxon: zaktualizowałem linki do zarchiwizowanych wersji – Leftium

Powiązane problemy