Cómo vincular c a javascript
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 p>
.
/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>
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{ p>
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;
}
}} p>
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> 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: p>
¡Felicitaciones por vincular exitosamente JS al código local!