2010-06-18 5 views
29

El official examples de exponer una clase Point parece suponer que habrá un número fijo de instancias en su programa. No está claro cómo se asignan nuevas instancias en el código C++, cuando se llama a new en Javascript.¿Cómo expone una clase de C++ en el motor de Javascript de V8 para que se pueda crear utilizando una nueva?

¿Cómo expondrías una clase que puede tener varias instancias? Por ejemplo, una clase de archivo:

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

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

Respuesta

-11

no sé cómo lograr esto en el motor V8 de Js exactamente, pero que en el mundo de Python, puede simplemente hacer lo siguiente. la clase Image:

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

escribir algunas funciones de contenedor y exponer estas funciones al mundo 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(); } 

añadir los siguientes códigos para su archivo JS:

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

y ahora puedes hacer que tu código funcione Además, los códigos anteriores no tienen en cuenta el mecanismo de recolección de basura, así que preste especial atención. ¡Disculpe por mi inglés borken!

+0

¿Qué ocurre con la exportación de funciones definidas? – Basilevs

+1

Sí, Python tiene una gran API para esto. ¡Es por eso que V8 es tan confuso! ¿Por qué no hay V8 :: FunctionTemplate :: SetClassAllocator (AllocateFn, FreeFn)? –

+2

v8 es mucho más rápido que python, aunque – ShrekOverflow

30

Este es el mejor blog post I could find on exposing C++ objects to V8 Javascript. Entra en detalles más profundos y lo divide en pasos más pequeños con fragmentos de código. Tenga cuidado: los fragmentos de código tienen pequeñas inconsistencias y me llevó varias lecturas entender. Leer mi breve resumen de antemano puede ayudar:

  1. Los objetos deben estar envueltos en plantillas V8. Nota: El ejemplo de Google usa ObjectTemplates, pero el autor explica por qué prefiere FunctionTemplates.
    1. Crear una plantilla de función. Las instancias de esta plantilla tienen un campo interno para almacenar la dirección de memoria del objeto C++. También obtienen los métodos de acceso de la clase.
    2. Crea una función wrapObject() que envolverá un objeto C++ en una de estas plantillas de función.
  2. El constructor también debe ser envuelto en un (diferente) plantilla V8. Se usa una plantilla diferente para evitar recursiones no deseadas. (Se describe un método para combinar ambas plantillas en una al final de la publicación del blog).
    1. Cree otra FunctionTemplate. Esta plantilla simplemente conecta el ámbito global de JavaScript (donde se llamará new) al constructor de C++.
    2. Realice el método que la plantilla llamará. Este método realmente usa el operador C++ new y llama al constructor de la clase C++. Luego envuelve el objeto llamando al método wrapObject() creado en el paso 1.2.

Ahora, la memoria asignada en el paso 2.2 debe ser delete 'd algún tiempo.Actualización: La siguiente entrada del blog, "Persistent Handles," cubre esto en detalle.

Mis notas sobre el actual code alluded to in these blog posts:

  • El método wrapPoint() en el blog es en realidad análogo al método unwrap() en el código real; nowrap()
  • Para encontrar otros puntos comunes entre el código, la búsqueda de: SetInternalFieldCount(0, constructorCall
  • El código real parece hacer la gestión de memoria utilizando el método MakeWeak() para establecer un método de devolución de llamada que hace la limpieza.
+0

la publicación de blog que vinculó en la parte superior está muerta – xaxxon

+0

@xaxxon: Actualicé los enlaces con versiones archivadas – Leftium

Cuestiones relacionadas