Archived

This forum has been archived. Please start a new discussion on GitHub.

slice2cs: struct/class unmarshalling problem

kwaclaw
kwaclaw Oshawa, Canada
I have a struct defined in Slice that is mapped to a class in C#, but I get a null-reference exception on unmarshalling. Here is the Slice:
["clr:property"]
  struct Action {
    string Key;
    string Description;
  };
  
  ["clr:property"]
  struct ActionPermission {
    ::IServices2ICE::Action Action;
    bool IsAuthorized;
  };
  
  sequence<ActionPermission> ActionPermissionSeq;

  ["ami", "amd"] interface ClassifiedServices {
    . . .
    idempotent OpStatus GetClientPermissions(
        string clientGroupKey,
        string orderStatus,
        out ActionPermissionSeq permissions
      )
      throws ServiceError;
  };

Now, debugging it, I can see that exception happens in the unmarshalling code for ActionPermission:
public void read__(IceInternal.BasicStream is__)
        {
            Action_prop.read__(is__);
            IsAuthorized_prop = is__.readBool();
        }

When it is called, Action_prop is null, leading to the exception.

Karl

Comments

  • kwaclaw
    kwaclaw Oshawa, Canada
    kwaclaw wrote: »
    I have a struct defined in Slice that is mapped to a class in C#, but I get a null-reference exception on unmarshalling.

    It seems the marshalling code has the same problem:
    public void write__(IceInternal.BasicStream os__)
            {
                Action_prop.write__(os__);
                os__.writeBool(IsAuthorized_prop);
            }
    

    It looks as if the code was generated assuming that Action was mapped to a struct instead of a class.

    Karl
  • matthew
    matthew NL, Canada
    Thanks Karl we'll look into this.
  • Karl,

    I'm looking at your problem. Unfortunately, the fix isn't entirely trivial (and I was away on vacation all last week), which is why this is taking so long. I'll have a patch for you by tomorrow.

    Cheers,

    Michi.
  • kwaclaw
    kwaclaw Oshawa, Canada
    michi wrote: »
    Karl,

    I'm looking at your problem. Unfortunately, the fix isn't entirely trivial (and I was away on vacation all last week), which is why this is taking so long. I'll have a patch for you by tomorrow.

    Cheers,

    Michi.

    Thanks, that is OK, we are still in development, and there is a simple workaround.

    And even you are entitled to some vacation. :)

    Karl
  • Hi Karl, I've post a patch for this problem. Please let me know how you go with that.

    Cheers,

    Michi.
  • kwaclaw
    kwaclaw Oshawa, Canada
    michi wrote: »
    Hi Karl, I've post a patch for this problem. Please let me know how you go with that.

    Cheers,

    Michi.

    There is now another issue with the generated code (in another part of my Slice) that does not allow it to compile. The problem is when a struct is mapped to a C# struct. The generated code does not initialize the struct when reading it from the stream. Here is the code generated - the function is the one called by IceInternal.DispatchStatus dispatch__(). I hope this is sufficient detail for you:
    public static IceInternal.DispatchStatus GetPackagePubDates___(CommonServices obj__, IceInternal.Incoming inS__, Ice.Current current__)
            {
                checkMode__(Ice.OperationMode.Idempotent, current__.mode);
                IceInternal.BasicStream is__ = inS__.istr();
                string packageKey;
                packageKey = is__.readString();
                IServices2ICE.Date startDate;  // = new IServices2ICE.Date();
                startDate.read__(is__);
                string classKey;
                classKey = is__.readString();
                AMD_CommonServices_GetPackagePubDates cb__ = new _AMD_CommonServices_GetPackagePubDates(inS__);
                try
                {
                    obj__.GetPackagePubDates_async(cb__, packageKey, startDate, classKey, current__);
                }
                catch(_System.Exception ex)
                {
                    cb__.ice_exception(ex);
                }
                return IceInternal.DispatchStatus.DispatchAsync;
            }
    

    The type IServices2ICE.Date is a struct, and it should be initialized by calling the default struct constructor, see the comment in the code.

    Because of the compile issue I haven't tested your patch yet, although the generated code looks OK for it.

    Karl
  • Hi Karl,

    my apologies--I missed two spots in the code generator that were affected by the changes.

    I've updated the patch. Could you try again please?

    Thanks,

    Michi.
  • kwaclaw
    kwaclaw Oshawa, Canada
    michi wrote: »
    Hi Karl,

    my apologies--I missed two spots in the code generator that were affected by the changes.

    I've updated the patch. Could you try again please?

    Thanks,

    Michi.

    Good news - it works now.

    Thanks,


    Karl