C#-App marshal very complex structures.

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • cleanrabbit
    New Member
    • Nov 2007
    • 3

    C#-App marshal very complex structures.

    Hello!

    I hate having to do this, because im almost certain there is someone in the world that has come across this problem and i just havent found their solution yet, so i do appologise if this has already been covered.

    I have been trying to learn c# as fast as possible in the last month and in doing so i have been re-visiting old C/C++ problems and trying to overcome them in C#.

    What i have is a very complex serise of structures. Id rather not change them, as it would cause a lot of work through the rest of the app, however they are causing me problems when it comes to saving the data they contain. My app passes the content of the structures through an encryption algorithem as a byte array, and so here is where the problem starts.

    My structures are nested as many as five-deep, all containing strings, string arrays and arrays of other structures (did i mention its a nightmare?)

    I have made some head-way with this, and can quite successfully convert a structure to a byte array using the following code-

    Code:
    static byte [] StructureToByteArray(object obj)
    {
    	int len = Marshal.SizeOf(obj);
    	byte [] arr = new byte[len];
    	IntPtr ptr = Marshal.AllocHGlobal(len);
    	Marshal.StructureToPtr(obj, ptr, true);
    	Marshal.Copy(ptr, arr, 0, len);
    	Marshal.FreeHGlobal(ptr);
    	return arr;
    }
    I have tried many changes to this code, but i always seem to get an error when handling more than one nested structure (I.E struct A contains struct B and struct C) or structures nested more than 1 deep (I.E struct A contains struct B which contains struct C).

    The errors i am getting are as follows:-

    "Object reference not set to an instance of an object"

    - when working with deep nested structures,or the following error :-

    "Type ssc.app.structD ata can not be marshaled as an unmanaged structure; no meaningful size or offset can be computed."

    - when working with several structures nested in the same structure

    Any solutions to my problem would be of great help (including telling me to rip it all out and start again =))

    Kind regards,
  • Plater
    Recognized Expert Expert
    • Apr 2007
    • 7872

    #2
    My advice: Avoid using Structs if you can. Use Classes instead, they're slightly easit to work with.

    I've never had to use the Marshalling stuff ( I avoiding using Serializing in Java and by golly I'll avoid Marshalling in .NET) But it rather seems like sizeof() would not work for struct with another struct in it, unless the nested structure already had a definitive size determined for it?

    I like classes because I can have a constructor like:
    Code:
    public myclass(byte[] DataBytes)
    {
    //...
    }
    And a function like:
    Code:
    public byte[] GetDataBytes()
    {
    //...
    }

    Comment

    • cleanrabbit
      New Member
      • Nov 2007
      • 3

      #3
      Thank you for the reply.

      I had a feeling you would tell me to switch to classes. Thankfully that shouldn’t be "too" much work, however I’m still a little confused with how you think I should be able to convert these classes into a byte array. One of the biggest problems is that I do not know the contents of any of my data until the moment I want to encrypt this and save it, and I am trying to minimize the usage of encrypt while keeping things straight forward enough to decrypt my data later on. encrypt/decrypt naturally take a lot of time to complete, so I would rather have one large byte array which I can feed through the encrypter in one go, than several calls with much less data.
      To this extent, I feel I would either have to update a byte array in each class which contains the classes data and gather this when I want to encrypt it all, or I would have to traverse through each class getting to the deepest nested class, and work backwards through all my classes, generating the byte array as I go until I have all my data in one byte array ready to be passed to the encrypter (and in both cases make sure I know the order the data is stored in the array, so I know how to pull it apart when exiting the decrypter after a load!)

      I originally went for structures, as I knew I could convert a structure to a byte array quite easily, however I seem to have quickly lost myself in the scale of this application. Naturally, I can foresee problems arising again later where my array of structures (which each contain a couple of structures within them each of them) need converting. Oh joy.

      I’m starting to feel that my data structures are over complicated and could really be re-done in a better way. I would really appreciate any ideas on how to overcome these problems.

      Comment

      • Plater
        Recognized Expert Expert
        • Apr 2007
        • 7872

        #4
        Well as far as byte[]->class and back:
        Code:
        public class DispValueType
        {
           public Int32 stat = 0;
           public float[] vals = new float[18];
           public byte[] theData= new byte[0];
        
           public DispValueType(byte[] mybuff)
           {
              if (mybuff.Length != (4 + (vals.Length * 4)))
              {
                 return;//not enough data
              }
              theData = mybuff;
              stat = MyConversions.MakeInt32(mybuff, 0);
              for (int i = 0; i < vals.Length; i++)
              {
                 vals[i] = MyConversions.MakeFloat(mybuff, 4 + (i * 4));
              }
           }
        }//end of class
        As for the rest of, not sure I really know much about what you're doing, I just didn't want to leave you hanging without a response.

        Comment

        • cleanrabbit
          New Member
          • Nov 2007
          • 3

          #5
          Thanks for getting back to me.
          I will look into that code and see what i can do with it.
          Thanks!

          Comment

          Working...