Loading ...
Sorry, an error occurred while loading the content.

How to call a method from C?

Expand Messages
  • Jonas Eschenburg
    Hi all! I am a CS student living in Germany. The last couple of days I have been trying to incorporate Io as a scripting language into a game project of mine.
    Message 1 of 4 , Aug 28, 2004
    View Source
    • 0 Attachment
      Hi all!

      I am a CS student living in Germany. The last couple of days I have been
      trying to incorporate Io as a scripting language into a game project of
      mine. So far, this has been a very pleasing experience, but I could use
      some some help now.

      I am basically trying to do
      Matrix dim(3,1)
      from C++. The code I have written is:

      // Get the Lobby and Matrix Objects. So far, everything works
      // as expected.
      IoObject *lobby = state->lobby;
      IoObject *matrix = IoObject_rawClone(
      IoObject_getSlot_(lobby,
      IoState_stringWithCString_(state, "Matrix")));

      // Setup locals object. Do i have to do that or is there an
      // easier way?
      IoObject *locals = IoObject_rawClone(
      IoObject_getSlot_(lobby,
      IoState_stringWithCString_(state, "Locals")));
      IoObject_setSlot_to_(locals,
      IoState_stringWithCString_(state, "self"), matrix);
      IoObject_setSlot_to_(locals,
      IoState_stringWithCString_(state, "sender"), lobby);

      // Setup message object with 2 args. What exactly does
      // "cached arg" mean?
      IoMessage *dimMessage = IoMessage_newWithName_(state,
      IoState_stringWithCString_(state, "dim"));
      IoMessage_setCachedArg_toInt_(dimMessage, 0, 3);
      IoMessage_setCachedArg_toInt_(dimMessage, 1, 1);
      IoObject *result = IoObject_doMessage(matrix,locals,dimMessage);

      Now, it says:
      Io.CFunction.invalidArgument: argument 0 to method 'dim' must be
      a Message, not a 'Number'

      What am I doing wrong?

      Thanks in advance,
      Jonas
    • Jonas Eschenburg
      Hi all! I am a CS student living in Germany. The last couple of days I have been trying to incorporate Io as a scripting language into a game project of mine.
      Message 2 of 4 , Aug 28, 2004
      View Source
      • 0 Attachment
        Hi all!

        I am a CS student living in Germany. The last couple of days I have been
        trying to incorporate Io as a scripting language into a game project of
        mine. So far, this has been a very pleasing experience, but I could use
        some some help now.

        I am basically trying to do
        Matrix dim(3,1)
        from C++. The code I have written is:

        // Get the Lobby and Matrix Objects. So far, everything works
        // as expected.
        IoObject *lobby = state->lobby;
        IoObject *matrix = IoObject_rawClone(
        IoObject_getSlot_(lobby,
        IoState_stringWithCString_(state, "Matrix")));

        // Setup locals object. Do i have to do that or is there an
        // easier way?
        IoObject *locals = IoObject_rawClone(
        IoObject_getSlot_(lobby,
        IoState_stringWithCString_(state, "Locals")));
        IoObject_setSlot_to_(locals,
        IoState_stringWithCString_(state, "self"), matrix);
        IoObject_setSlot_to_(locals,
        IoState_stringWithCString_(state, "sender"), lobby);

        // Setup message object with 2 args. What exactly does
        // "cached arg" mean?
        IoMessage *dimMessage = IoMessage_newWithName_(state,
        IoState_stringWithCString_(state, "dim"));
        IoMessage_setCachedArg_toInt_(dimMessage, 0, 3);
        IoMessage_setCachedArg_toInt_(dimMessage, 1, 1);
        IoObject *result = IoObject_doMessage(matrix,locals,dimMessage);

        Now, it says:
        Io.CFunction.invalidArgument: argument 0 to method 'dim' must be
        a Message, not a 'Number'

        What am I doing wrong?

        Thanks in advance,
        Jonas
      • Steve Dekorte
        Hi Jonas, ... Does this solution suit your needs?: result = IoObject_rawDoString_label_(state- lobby, IOSTRING( Matrix dim(3,1) ), IOSTRING( [internal
        Message 3 of 4 , Aug 28, 2004
        View Source
        • 0 Attachment
          Hi Jonas,

          On Aug 28, 2004, at 10:46 AM, Jonas Eschenburg wrote:
          > I am basically trying to do
          > Matrix dim(3,1)

          Does this solution suit your needs?:

          result = IoObject_rawDoString_label_(state->lobby,
          IOSTRING("Matrix dim(3,1)"), IOSTRING("[internal stuff]"));

          This will work just as well for multiple lines of code. If you need to
          call this frequently, then you can avoid the overhead of compiling the
          string by doing:

          aMessage = IoObject_rawDoString_label_(state->lobby,
          IOSTRING("message(Matrix dim(3,1))"), IOSTRING("[internal stuff]"));
          IoState_retain_(state, aMessage);

          once, and then calling:

          IoMessage_locals_performOn_(aMessage, state->lobby, state->lobby);

          each time you want to execute that code. Here, I just used the lobby as
          the locals and the target to eval the message in, but you could use any
          object.

          The IoState_retain_() call is there to permanently prevent aMessage
          from being garbage collected. If this code is in a primitive, then
          you'd want to use the normal .._mark() mechanism to deal with garbage
          collection instead.

          > from C++. The code I have written is:
          >
          > // Get the Lobby and Matrix Objects. So far, everything works
          > // as expected.
          > IoObject *lobby = state->lobby;
          > IoObject *matrix = IoObject_rawClone(
          > IoObject_getSlot_(lobby,
          > IoState_stringWithCString_(state, "Matrix")));
          >
          > // Setup locals object. Do i have to do that or is there an
          > // easier way?

          There is no need to do this.
          ...

          > // Setup message object with 2 args. What exactly does
          > // "cached arg" mean?

          It means the Message object for the argument caches it's result - which
          in this case is a Number object.

          > IoMessage *dimMessage = IoMessage_newWithName_(state,
          > IoState_stringWithCString_(state, "dim"));
          > IoMessage_setCachedArg_toInt_(dimMessage, 0, 3);
          > IoMessage_setCachedArg_toInt_(dimMessage, 1, 1);
          > IoObject *result = IoObject_doMessage(matrix,locals,dimMessage);

          > Now, it says:
          > Io.CFunction.invalidArgument: argument 0 to method 'dim' must be
          > a Message, not a 'Number'
          >
          > What am I doing wrong?

          The IoObject_doMessage() call is the problem - it's for the Object do()
          method, so it expects the message to execute to be it's argument.
          Replacing that call with this one should work:

          IoMessage_locals_performOn_(dimMessage, locals, matrix);

          -- Steve
        • Jonas Eschenburg
          Hi Steve, ... This is indeed a good solution for my task, since I will always call dim with the same parameters. It is shorter to just compile a message once
          Message 4 of 4 , Sep 1, 2004
          View Source
          • 0 Attachment
            Hi Steve,

            >Does this solution suit your needs?:
            >[ ... ]
            >aMessage = IoObject_rawDoString_label_(state->lobby,
            > IOSTRING("message(Matrix dim(3,1))"), IOSTRING("[internal stuff]"));
            >IoState_retain_(state, aMessage);
            >
            >once, and then calling:
            >
            >IoMessage_locals_performOn_(aMessage, state->lobby, state->lobby);
            >
            >each time you want to execute that code. Here, I just used the lobby as
            >the locals and the target to eval the message in, but you could use any
            >object.
            >
            >
            This is indeed a good solution for my task, since I will always call
            "dim" with the same parameters. It is shorter to just compile a message
            once and for all than calling the corresponding C functions every time.

            >> // Setup locals object. Do i have to do that or is there an
            >> // easier way?
            >>
            >>
            >
            >There is no need to do this.
            >
            >
            Seems that the locals object in the C functions is the locals of the
            message sender. So I can just as well pass Lobby as the locals object?
            Which is what I did, and it worked.

            Another thing I noticed is that in order to have the "init" function
            called after rawCloning an object, you have to manually do:

            IoObject_initClone_(lobby, lobby, NULL, newObject);


            so long,
            Jonas
          Your message has been successfully submitted and would be delivered to recipients shortly.