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

User defined classes sliced?


I'm defining a method inside an interface to take in a user defined base class A. For example

void doSomething (A a)

The client and the server talks thru glacier2 and I have a session class. So really the call goes from the client to the session class, then to the server. My client is calling doSomething with a derived class B (B extends A), but it seems like by the time it gets to the session class, B has been sliced to A. I called ice_id() on the argument in the session class and it gives me the type for A. I believe I have to link the session with B's definition so that it doesn't get sliced? I did that and it still gets sliced.

I'm wondering if I'm missing anything.

I'm thinking of an alternative approach where instead of using

void doSomething(A a), maybe I should do

void doSomething(ByteSeq a). So I'll send the serialized version of the class (using streaming API) and then deserialize it on the server. But I don't want to do that if I don't have to. Having said that maybe that's a better approach anyway? I don't have to worry about linking in all the derived classes, which may not be known ahead of time.



  • bernard
    bernard Jupiter, FL
    Hello Budyanto,

    If the intermediary server does not need to access the parameters of the requests--it's just forwarding the request as-is to the target server--then the best solution is indeed to pass this request as a "marshaled blob", or Blobject. See for example the Dynamic Ice Part 1 article in

    Your client would still use regular invocations (with generated code), and the target server would use the regular dispatch (with generated code). It's just the intermediary server that would use the Blobject API without any generated code. Services like Glacier2 and IceStorm are themselves "intermediary servers" and use Blobjects to forward requests without unmarshaling/remarshaling them.

    From your description, it sounds like this is what you want.

    Now, if your intermediary server needs to look inside these requests, for example read the data member of class A parameters, then passing marshaled blobs (Blobjects) won't work.

    If you want to avoid the slicing of any class data member, you will need to link with the generated code for the most-derived classes; while this should definitely work, it is indeed not the most convenient & easy to maintain. The ability to preserve class slices through intermediary servers without linking generated code would be a nice new feature for Ice.

    Best regards,
  • Hi Bernard,

    Thanks for your response.

    I found out that in order for it to get linked I had to at least include the header file that contains the definition for the derived class. It works after that.

    Thanks for the pointer on BlobObject. I'll consider that solution.

    Yes being able to preserve class slices thru intermediary would indeed be a nice feature to have.

    On a separate note, is there an easy way to stringify slice classes so that it's human readable? It's mostly for logging purposes.
  • bernard
    bernard Jupiter, FL
    Hi Budyanto,

    Ice does not generate code to stringify or print the data members of a class, struct, or any other type ... I am afraid you need to write your own function.

    Best regards,