JS_CallFunctionName crashed on iAP finished callback

jsval onBuyItem(const char* itemID, bool success){
  ScriptingCore* sc = ScriptingCore::getInstance();
  jsval res;
  jsval *argv = new jsval[2];

  argv[0] = std_string_to_jsval(sc->getGlobalContext(),std::string(itemID));
  argv[1] = BOOLEAN_TO_JSVAL(success);
  JS_CallFunctionName(sc->getGlobalContext(), sc->getGlobalObject(), "onBuyItem", 2, argv, &res);   // [1] call global JS function onBuyItem
  delete [] argv;
  return res ;
}

this is my C++ callback function, will be called when iAP finished…
it will crashed in line [1]…

but when i directly call it on buyItem(), everything worked fine… only when it be called Asynchronously, app will crash…

this issue bothered me for a whole day… i need some help plz…

That’s because the context wasn’t available when you invoke JS_CallFunctionName, all asynchronous function call have this problem. It can be fixed by adding JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET :

jsval onBuyItem(const char* itemID, bool success){
  ScriptingCore* sc = ScriptingCore::getInstance();
  jsval res;
  jsval *argv = new jsval[2];

  JSB_AUTOCOMPARTMENT_WITH_GLOBAL_OBJCET
  argv[0] = std_string_to_jsval(sc->getGlobalContext(),std::string(itemID));
  argv[1] = BOOLEAN_TO_JSVAL(success);
  JS_CallFunctionName(sc->getGlobalContext(), sc->getGlobalObject(), "onBuyItem", 2, argv, &res);   // [1] call global JS function onBuyItem
  delete [] argv;
  return res ;
}

can you show me how you bind this function to the callback of buyItem ?

1 Like

thanks very much for replying, your answer solved this question… brilliant!
btw, we’ve met before… last time in GuangZhou Cocos Dev Meeting i asked you some questions about cocos-js/html5 :smile: it’s very kind of you~

thank you again~

actually i solved this issue by this way last night:

jsval onBuyItem(const char* itemID, bool success){
  ScriptingCore* sc = ScriptingCore::getInstance();

  jsval res;
  jsval *argv = new jsval[2];

  argv[0] = std_string_to_jsval(sc->getGlobalContext(),std::string(itemID));
  argv[1] = BOOLEAN_TO_JSVAL(success);

  JS::RootedValue out(sc->getGlobalContext());
  JS_GetProperty(sc->getGlobalContext(), sc->getGlobalObject(),"Helper", &out);
  sc->executeFunctionWithOwner(out,"onBuyItem", 2, argv, &res );
  delete [] argv;

  return res ;
}

and JS :

Helper.onBuyItem = function(itemID, success){/*...*/}

Ah ha, really ? That was the first time that I give a speed about Cocos2d-JS, a little bit nerves, hope it was not bad for you.