1.2.2beta2的安卓版evalString可用么

在这个版本下,安卓调用这个方法Cocos2dxJavascriptJavaBridge.evalString,直接fata sigal 11了呢?

Cocos2dxJavascriptJavaBridge.evalString(“console.log(’######java onEnterForeground#######’);”);
执行这个语句就报错直接闪退。

在1.3.0rc1上可以执行,但是1.3.0rc1上有很多别的问题,目前的项目没法使用

你把 1.3 的 ScriptingCore::evalString 实现搬一下过去,注意一下,部分 Spidermonkey 接口不同

1赞

我把1.3的ScriptingCore.cpp文件中的evalString方法替换到1.2.2了:
bool ScriptingCore::evalString(const char *string, JS::MutableHandleValue outVal, const char filename, JSContext cx, JS::HandleObject global)
{
JSAutoCompartment ac(cx, global);
JS::PersistentRootedScript script(cx);

JS::CompileOptions op(cx);
op.setUTF8(true);

std::string content = string;

bool ok = false;
bool evaluatedOK = false;
if (!content.empty())
{
    ok = JS::Compile(cx, global, op, content.c_str(), content.size(), &(script) );
}
if (ok) {
    evaluatedOK = JS_ExecuteScript(cx, global, script, outVal);
    if (false == evaluatedOK) {
        cocos2d::log("Evaluating %s failed (evaluatedOK == JS_FALSE)", content.c_str());
        JS_ReportPendingException(cx);
    }
}
else {
    cocos2d::log("ScriptingCore:: evaluateScript fail: %s", content.c_str());
}
return evaluatedOK;

}

bool ScriptingCore::evalString(const char *string, JS::MutableHandleValue outVal)
{
JS::RootedObject global(_cx, _global->get());
return evalString(string, outVal, nullptr, _cx, global);
}

bool ScriptingCore::evalString(const char *string)
{
JS::RootedValue retVal(_cx);
return evalString(string, &retVal);
}
这三个方法直接替换过去吧?头文件里的相应声明也替换了。

哪几个SpiderMonkey的接口不同呢?
这些改变的接口如果被覆盖,是否会影响别的功能的使用呢?

我调用js就是为了解决游戏内手动暂停,然后切出,再切入时,安卓端的表现是画面暂停,但是有声音的bug,我想切入后是全暂停的状态。

官方可以打个1.2.2beta2的补丁版本么?今天必须完成bug修改任务,昨天用1.3的时候把这个暂停切出切入 的bug改掉了,换回这个1.2因为方法不支持,又无法实现了,可是已经在禅道里说解决了这个相关的几个bug。官方可以支持下么?

其实我们是希望解决你的项目在 1.3 上的问题的,但是目前因为我们没有你的项目,所以没办法调试和重现问题,1.2.2 的 evalString 你实现以后有没有遇到问题?比如编译不通过。

我之前说错了, Spidermonkey 版本是一样的,所以 API 没有区别,不过绑定层接口可能有一些区别,你先试试直接搬过去能不能用,如果不能用把错误发出来我帮你解决

1赞

我把ScriptingCore的cpp和h文件修改了,然后重新发布打包,安卓的启动后直接:
10-28 01:58:35.805: A/libc(14886): Fatal signal 11 (SIGSEGV) at 0x00000004 (code=1), thread 14903 (Thread-6318)

1.3的时间来不及了。今天必须把所有bug解决掉了。后续再用1.3来弄。

启动后是调用了 evalString 吗?

嗯,放在helper类的方法里:
public static void onEnterForeground() {

    if (sCocosSound != null) {
        sCocosSound.onEnterForeground();
    }

    if (sCocosMusic != null) {
        sCocosMusic.onEnterForeground();
    }
    Cocos2dxJavascriptJavaBridge.evalString("console.log('######java onEnterForeground#######');");   
	//Cocos2dxJavascriptJavaBridge.evalString("cc.find('Game').getComponent('Player').onBeforeWillEnterForeground();");
}

Android 调试很困难,能不能用 Visual Studio 或者 Xcode 跟踪一下崩溃调用栈?

一般建议等 Mac / Win 版本跑通没问题了再做 Android

1赞

我用Xcode试试,creator构建,编译时候没通过:

Undefined symbols for architecture i386:
“ScriptingCore::evalString(char const*, JS::MutableHandleJS::Value)”, referenced from:
-[AppController applicationWillResignActive:] in AppController.o
-[AppController applicationDidBecomeActive:] in AppController.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

** BUILD FAILED **

这是在 iOS 平台找不到 ScriptingCore::evalString(char const*, JS::MutableHandle) 的实现,你检查一下 cpp 文件中的匹配,有可能是 const char * 改为 std::string 了

cpp中的实现也是从1.3中直接复制的呀,我看了是const char *

/*
bool ScriptingCore::evalString(const char *string, jsval outVal, const char filename, JSContext cx, JSObject global)
{
if (cx == NULL)
cx = _cx;
if (global == NULL)
global = _global.ref().get();

JSAutoCompartment ac(cx, global);
JS::RootedObject jsglobal(cx, global);
return JS_EvaluateScript(cx, jsglobal, string, (unsigned)strlen(string), "ScriptingCore::evalString", 1);

}
*/
//changed
bool ScriptingCore::evalString(const char *string, JS::MutableHandleValue outVal, const char filename, JSContext cx, JS::HandleObject global)
{
JSAutoCompartment ac(cx, global);
JS::PersistentRootedScript script(cx);

JS::CompileOptions op(cx);
op.setUTF8(true);

std::string content = string;

bool ok = false;
bool evaluatedOK = false;
if (!content.empty())
{
    ok = JS::Compile(cx, global, op, content.c_str(), content.size(), &(script) );
}
if (ok) {
    evaluatedOK = JS_ExecuteScript(cx, global, script, outVal);
    if (false == evaluatedOK) {
        cocos2d::log("Evaluating %s failed (evaluatedOK == JS_FALSE)", content.c_str());
        JS_ReportPendingException(cx);
    }
}
else {
    cocos2d::log("ScriptingCore:: evaluateScript fail: %s", content.c_str());
}
return evaluatedOK;

}

bool ScriptingCore::evalString(const char *string, JS::MutableHandleValue outVal)
{
JS::RootedObject global(_cx, _global->get());
return evalString(string, outVal, nullptr, _cx, global);
}

bool ScriptingCore::evalString(const char *string)
{
JS::RootedValue retVal(_cx);
return evalString(string, &retVal);
}
//changed end

我用的binary方式,我修改了下发布路径,就可以在creator上编译通过了,bianry方式编译不会自动更换原路径下的so库么?

在xcode下编译安装报错:

Undefined symbols for architecture arm64:
“ScriptingCore::evalString(char const*, JS::MutableHandleJS::Value)”, referenced from:
-[AppController applicationWillResignActive:] in AppController.o
-[AppController applicationDidBecomeActive:] in AppController.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

呃,我仔细看了一下,你是在一启动就调用了 evalString,这样是有问题的,这个时候 JS 环境都还没准备好,在 AppDelegate::applicationDidFinishLaunching 里面才会初始化 JS 引擎。

Undefined Symbols 问题我不是很理解,按理说如果找不到应该是编译阶段就报错了,链接阶段报错说明头文件引用没问题,已经找到函数定义,但是函数实现找不到,一般情况下都是因为函数的参数或者返回值类型在声明和定义不同导致的,不过我没在你贴出来的代码里找到问题

Binary 如果可以编译通过说明还是你引用的引擎有可能有问题,你是用的 Creator 标准内置引擎完全没有改动吗?

ios在1.2和1.3里,这个位置调用没有问题的,可以成功调用,并且通过逻辑解决了暂停切出切入的bug。安卓1.3也可以成功调用。

另:引擎从来没改过。只是这次修改了scriptingcore的h和cpp

现在用未改动的1.2,ios可以evalstring,只是没有返回值,安卓直接退出。

官方可以打个1.2.2beta的补丁包么,只增加安卓的evalstring功能的。安卓的evalstring在以前的低版本中也是可以的吧

你是用干净的环境,build 出原生版本,然后在原生版本的 iOS_mac 工程里面修改这些内容,然后重新编译的对吧?

你把你的 ScriptingCore.h / .cpp 以及调用了 evalString 的文件一起发给我看看吧

我用的binary方式,我到creator的安装目录下,找到cpp和h文件,修改的。
source.zip (26.3 KB)

怪不得,binary 摸版中的 cocos 引擎是预编译好的,所以你改 creator 目录下的 cpp 没有用。你需要用 link 或者 default 摸版

附件是default方式,creator编译未通过的错误:
native.log.zip (6.0 KB)