Home Bug Reports

slice2cs: struct/class unmarshalling problem

kwaclawkwaclaw Oshawa, CanadaMember Karl WaclawekOrganization: Personal
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

  • kwaclawkwaclaw Oshawa, CanadaMember Karl WaclawekOrganization: Personal
    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
  • matthewmatthew NL, CanadaMember Matthew NewhookOrganization: ZeroC, Inc.Project: Internet Communications Engine ✭✭✭
    Thanks Karl we'll look into this.
  • michimichi Member Michi HenningOrganization: Triodia TechnologiesProject: I have a passing interest in Ice :-) ✭✭✭
    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.
  • kwaclawkwaclaw Oshawa, CanadaMember Karl WaclawekOrganization: Personal
    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
  • michimichi Member Michi HenningOrganization: Triodia TechnologiesProject: I have a passing interest in Ice :-) ✭✭✭
    Hi Karl, I've post a patch for this problem. Please let me know how you go with that.

    Cheers,

    Michi.
  • kwaclawkwaclaw Oshawa, CanadaMember Karl WaclawekOrganization: Personal
    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
  • michimichi Member Michi HenningOrganization: Triodia TechnologiesProject: I have a passing interest in Ice :-) ✭✭✭
    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.
  • kwaclawkwaclaw Oshawa, CanadaMember Karl WaclawekOrganization: Personal
    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
Sign In or Register to comment.