1

I am trying to run an Action that sends data to the javascript on the browser, and when the browser finishes it runs a callback, and when the callback completes, it runs the item in the C# which runs the original callback.

Here are is the call order: GameSmart.User.IsGuest(Action origCallback) -> IsGuestUser(/*Executes the javascript*/) -> GuestResponse(string json) -> origCallback()

Once I compile and run the game, I get the following message in the chrome console:

MarshalDirectiveException: Cannot marshal type 'GameSmart.Response`1<GameSmart.IsGuestResponse>'.

I am not sure what that is saying or even means. Is there something I am doing wrong?

This is the class GameSmart.User:

public class User : API {
  [DllImport("__Internal")]
  public static extern void IsGuestUser(Response<IsGuestResponse> response);

  [MonoPInvokeCallback(typeof(Action))]
  public static void GuestResponse(Response<IsGuestResponse> r, string data) {
    r.callback(JsonUtility.FromJson<IsGuestResponse>(data));
  }

  public static void IsGuest(Action<IsGuestResponse> callback) {
    IsGuestUser(new Response<IsGuestResponse>(callback));
  }
}

Here are the Response/Respond classes:

public class Respond { }

public class Response<T> : Respond {
  public Action<T> callback;

  public Response(Action<T> cb) {
    callback = cb;
  }

  public void Action(Action act, params object[] args) {
    act();
  }

}

The JavaScript portion looks like this:

var GameSmartJs = {
  $GameSmartJs: {},

  IsGuestUser: function (obj) {
    gamesmart.user.isGuest(function (result) {
      this.runCallback('GuestResponse', obj, result);
    });
  },

  runCallback: function (callbackName, callback, result) {
    GameSmartJs[callbackName] = callback;
    Runtime.dynCall('vZ', callback, Pointer_stringify(result));
  }

};

autoAddDeps(GameSmartJs, '$GameSmartJs');
mergeInto(LibraryManager.library, GameSmartJs);

Edit

As per @Programmer suggested, to use _malloc and writeStringToMemory I tried this, and it produces the same error message.

IsGuestUser: function (obj) {
  gamesmart.user.isGuest(function (result) {
    GameSmartUser.GuestResponse = obj;
    var buffer = _malloc(lengthBytesUTF8(result) + 1);
    writeStringToMemory(result, buffer);
    Runtime.dynCall('vZ', obj, buffer);
  });
},
2
  • Maybe you should use _malloc and writeStringToMemory before passing the string the parameter in the Javascript side. Not totally sure but you should try that. Commented Jun 30, 2017 at 4:24
  • @Programmer that didn't seem to work, I updated the question with what I tried. Commented Jun 30, 2017 at 15:31

1 Answer 1

3

For the next soul that comes across this:

Runtime.dynCall('vZ', obj, buffer);

should be changed to

Runtime.dynCall('vi', obj, [buffer]);

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.