Red de conocimiento informático - Material del sitio web - Cómo vincular c a javascript

Cómo vincular c a javascript

Descargue el generador de enlaces, ruta local /Users/iven/Dev/bindings-generator

Para instalar y ejecutar MacPort en Mac OS X, su sistema debe tener instaladas las herramientas de desarrollo de línea de comandos de Apple. "

xcodebuild -license

Descargue e instale MacPort

Nota: si es usuario de Homebrew, primero debe desinstalar Homebrew porque Homebrew no es compatible con MacPort

También ejecute el comando "selfupdate" de MacPort para asegurarse de que esté instalada la última versión.

sudo port -v selfupdate

Una vez completada la actualización, utilice MacPort. Instale las dependencias de Python en la línea de comando

sudo port install python27 py27-yaml py27-cheetah

Verá lo siguiente:

Descargue llvm-3.3. Y descomprímalo en el directorio $HOME/bin. Si no hay un directorio bin, cree uno y cambie el nombre del archivo ZIP descomprimido a "clang llvm-3.3"

El directorio final se muestra a continuación: /. Users/guanghui/bin/clang llvm-3.3 (guanghui es el nombre del directorio de inicio local)

Código de muestra

La fuente del software generador de enlaces contiene un caso de uso de prueba de muestra. la carpeta binds-generator/test/simple_test

Configuración

Personalice los archivos "test/userconf.ini" y "test/user.cfg" según su entorno. p>

Nota: Los archivos con el sufijo ".sample" deben eliminarse, como "user.cfg.sample" y "userconf.ini.sample" "

[Predeterminado]<. / p>

androidndkdir=/Users/iven/Dev/android-ndk-r8c

clangllvmdir=/Users/iven/Dev/clang llvm- 3.1-x86_64-apple-darwin11

cxxgeneratordir=/Users/iven/Dev/bindings-generator-master

La configuración de user.cfg es la siguiente. La configuración de cfg es la siguiente

PYTHON_BIN=/ opt/local/Library/Frameworks/Python.framework/Versions/2.7/bin/ python2.7

Ejecutar ejemplo de prueba

.

/test.sh

Si el entorno está configurado correctamente, verá lo siguiente:

Error al analizar el encabezado:

1.lt;severity = Advertencia,

ubicación =lt; Archivo de ubicación de origen Ninguno, línea 0, columna 0>,

detalles = "argumento no utilizado durante la compilación: '-nostdinc '"gt;

details = "argument usedduring compile: '-nostdinc '"gt;

p>

No te preocupes por las advertencias, has terminado de ejecutar y el caso de prueba creó un "simple" archivo que contiene 3 archivos en el directorio "simple_test_bindings".

El archivo de encabezado .hpp de la clase vinculante

El archivo .cpp que implementa la clase vinculante

Describe cómo llamar (desde un script Java) a los métodos expuesto por el archivo .js clase C.

Ejecutar la prueba

Crear un proyecto JS básico Cocos2d-x. Agregue las carpetas "simple_test carpeta" y "simple_test_binding" al proyecto

Modifique la función de registro en "autogentestbindings.cpp" de la siguiente manera:

void Register_all_autogentestbindings(JSContext* cx, JSObject * obj) {

jsval nsval;

JSObject *ns;

JS_GetProperty(cx, obj."ts",amp;nsval

);

if (nsval == JSVAL_VOID) {

ns = JS_NewObject(cx, NULL, NULL, NULL);

nsval = OBJECT_TO_JSVAL(ns);

JS _SetProperty(cx, obj, "ts", y nsval

} else {

JS_ValueToObject(cx, nsval, y ns);

}

obj = ns;

js_ Register_autogentestbindings_SimpleNativeClass(cx, obj);

}

Nota: Si está en " test.ini", el código se generará automáticamente. No se requiere ninguna modificación.

target_namespace =ts

Regístrese en "AppDelegate"

Incluya el archivo de encabezado "autogentestbindings.hpp" y registre la función de devolución de llamada:

sc-gt;addRegisterCallback(register_all_autogentestbindings);

Agregue el siguiente código en la ubicación adecuada del archivo "hello.js". Localmente, la función "init f " se coloca en la primera escena.

var myClass=new ts.SimpleNativeClass();

var myStr=myClass.returnsACString();

var label = cc.LabelTTF.create(myStr) , "Helvetica", 20.0);

Limitaciones

El generador de enlaces tiene las dos limitaciones siguientes

Los parámetros numéricos automáticos no funcionan, por lo que es necesario escribirlos manualmente los contenedores para representar clases no funcionarán, por lo que deberá vincularlos manualmente, como se detalla en la siguiente sección.

Enlace JSB manual

Esta guía le mostrará cómo implementar el enlace JSB en su propio proyecto utilizando plantillas Cocos2d-x 2.14.

Primero, crea un proyecto usando la plantilla Cocos2d-js. En segundo lugar, veremos cómo llamar a funciones nativas desde JS. Finalmente, aprenderá cómo llamar código JS desde código nativo.

¡Ahora sí, comencemos! Usamos Mac OS X como nuestro entorno de desarrollo.

Paso 1. Cree un nuevo proyecto usando la plantilla Cocos2dx-js y cree una nueva clase C vinculada a JS.

Nombra el proyecto "JSBinding" y haz clic en "Siguiente", "Crear".

Crea una nueva clase e impleméntala.

Implemente la clase y vincúlela a JS más tarde.

Presione "comando N" para crear una nueva clase C llamada "JSBinding" con la ruta "OS X\C and C \C Class".

Añade el siguiente código en el archivo "JSBinding.h".

#include "cocos2d.h"

#include "ScriptingCore.h"

// Defina espacios de nombres para administrar el código y dejarlo claro

p>

espacio de nombres JSB {

clase JSBinding: público cocos2d::CCObject

{

público:

cocos2d estático: :CCScene* escena();

virtual bool init();

CREATE_FUNC(JSBinding);

void functionTest(); >

};

}

Ahora implemente la clase en JSBinding.cpp. Como se muestra a continuación:

bool JSB::JSBinding::init(){

bool bRef = false;

do{

cocos2d::CCLog("JSB init...") )

bRef = true;

} while (0);

return bRef;

p>

}

void JSB::JSBinding::functionTest(){

cocos2d::CCLog("Prueba de función...");

}

Paso 2.

Vincule el código C al código del script Java

Presione la tecla "comando N" para crear una nueva clase C y asígnele el nombre "JSB_AUTO" con la siguiente ruta. "Clase OS X\C y C\C".

Agrega algo de código en el archivo "JSB_AUTO.h"

#include "jsapi.h"

#include "jsfriendapi.h"

#include "ScriptingCore.h"

#include "JSBinding.h"

void Register_all(JSContext* cx, JSObject* obj);

Luego preste atención a la implementación de "JSB_AUTO.cpp".

#include "jsapi.h"

#include "jsfriendapi.h"

#include "ScriptingCore.h"

# incluir "JSBinding.h"

jsb_class-gt;convert = JS_ConvertStub;

jsb_class-gt;finalize = js_finalize;

jsb_class-gt;flags = JSCLASS_HAS_RESERVED_SLOTS (2);

Propiedades estáticas de JSPropertySpec[] = {

{0, 0, 0, JSOP_NULLWRAPPER, JSOP_NULLWRAPPER}

};

// Función de enlace Función de prueba

Funciones estáticas JSFunctionSpec[] = {

JS_FN("functionTest", js_functionTest, 1, JSPROP_PERMANENT | JSPROP_ENUMERATE),

JS_FS_END

};

//Enlazar función create()

JSFunctionSpec estática st_funcs[] = {

JS_FN(" create" , js_create, 0, JSPROP_PERMANENT | JSPROP_ENUMERATE),

JS_FS_END

};

// Constructor y prototipo de enlace

jsb_prototype = JS_InitClass (

cx, global,

NULL,

jsb_class,

js_constructor, 0,

propiedades,

funciones,

NULL,

st_funcs

JSBool encontrado

JS_SetPropertyAttributes (cx, global); , "JSB", JSPROP_ENUMERATE | JSPROP_ READONLY, & encontrado);

TypeTestlt;JSB::JSBindinggt;t;

js_type_class_t* p;

uint32_t typeId = t.s_id();

HASH_ FIND_INT(_js_global_type_ht, amp; typeId, p ​​

If (! p) {

p = (js_type_class_t* )malloc(sizeof(_js_global_type_ht));

p-gt; tipo = typeId

p-gt; jsclass = jsb_class;

p-gt; proto = jsb_prototype;

p-gt; parentProto = NULL;

HASH_ADD_INT(_ js_glob

al_type_ht, type, p);

}

}}

// Vincula el espacio de nombres JSB para identificar el espacio de nombres JSB en el código JavaScript

p >

void Register_all(JSContext* cx, JSObject* obj){

jsval nsval;

JSObject* ns;

JS_GetProperty(cx, obj, "JS", & nsval);

if (nsval == JSVAL_VOID) {

ns = JS_NewObject(cx, NULL, NULL, NULL);

nsval = OBJECT_TO_JSVAL(ns);

JS_SetProperty(cx, obj, "JSB ", amp; nsval);

}

else{

JS_ValueToObject(cx, nsval, amp; ns);

}

obj = ns;

js_register(cx, obj);

}

Ahora la mayor parte del trabajo está hecho, pero necesitamos registrarnos en "SpiderMonkey".

Abre "AppDelegate.cpp" y agrega el siguiente código

ScriptingCore* sc = ScriptingCore::getInstance();

sc-gt.addRegisterCallback(register_all ) ; //Agrega esta línea

Paso 3. Gestión de memoria

Agrega dos nuevas funciones antes de la función Register_all.

JSBool JSB_cocos2dx_retain(JSContext* cx, uint32_t argc, jsval *vp){

JSObject* thisObj = JS_THIS_OBJECT(cx, vp);

if ( thisObj ) {

js_proxy_t* proxy = jsb_get_js_proxy(thisObj);

if (proxy) {

((CCObject* )proxy-gt;ptr)-gt ;retain();

CCLog("¡Retener correctamente!");

devuelve JS_TRUE;

}

}}

JS_ReportError(cx, "Objeto nativo no válido");

devuelve JS_FALSE )

}

JSBool JSB_cocos2dx_release(JSContext* cx, uint32_t argc , jsval *vp){

JSObject* thisObj = JS_THIS_OBJECT(cx, vp);

if (thisObj) {

js_proxy_t* proxy = jsb_get_js_proxy(thisObj); p>

if (proxy) {

((CCObject* )proxy-gt;ptr)-gt;release();

CCLog( "¡Liberación exitosa!");

Devuelve JS_TRUE;

}

}

}

JS_ReportError( cx, "Objeto nativo no válido");

return JS_FALSE;

}

Agregue el siguiente código en la función Register_all:

JS_DefineFunction(cx, JSB_PROTOTYPE, "Retener", JSB_COCOS2DX_RETAIN, 0, JSprop_ Readonly | jsprop_perManent);

js_defineFunction (cx, jsb_prototype, "Retener", JSB, _cocos2dx_release, 0, jsprop_readonly | jsprop_ Permannt); /p>

Paso 4. Recuperar el código del script Java usando código C

Antes de que el código C recupere el código del script Java, agregue algo de código en el archivo "hello.js".

var testJSB = new JSB.JSBinding();

testJSB.callback = function(i, j){

log("JSB Callback" i j) ;

};

Luego abra "JSBinding.cpp" y agregue algo de código en "functionTest".

js_proxy_t* p = jsb_get_native_proxy(this);

jsval retval;

jsval v[] = {

v[0] = UINT_TO_JSVAL(32),

v[1] = UINT_TO_JSVAL(88),

v[1] = UINT_TO_JSVAL(88) TO_JSVAL(88)

};

ScriptingCore::getInstance()-gt;executeFunctionWithOwner(OBJECT_TO_JSVAL(p-gt;obj),

"callback", 2, v, amp;retval);

Utilice la función "executeFunctionWithOwner()" para simplificar el proceso de llamada a la función

Paso 5. Vincular la prueba

Utilice el siguiente código para vincular la prueba al archivo "hello .js".

var testJSB = new JSB.JSBinding();

testJSB.retain();

testJSB.functionTest();

testJSB.release();

Paso 6: Ahora saque (verifique) el proyecto

Si su carpeta es correcta, verá la siguiente interfaz en la ventana de depuración:

¡Felicitaciones por vincular exitosamente JS al código local!