none
Marshaling Structure with Nested Array of Structures RRS feed

  • Question

  • Okay,

    I'm not saying I'm going to do this, but I've come across a lot of information and found it best to simply ask about my design.

    Many times in the past, working with Delphi or C++, there have been quite a few really cool designs that allow for array management with allocated space.  I've written my own virtual memory manager for Delphi, at least for the larger chunks of data, not for the everyday application stack, and found one of the greatest abilities was to create a Pointer to an Array of any given type, and then create a point to the structure, and allocate SizeOf(Structure) + (Sizeof(ArrayType) * ArrayCount) and then simply point the structure field that is the  pointer to array to the end of the structure:  Struct.PtrArray = Addressof(Struct) + SizeOf(Struct).  and then the default language specific array management would handle the index iterations, so index 0 is at the Address PtrArray points to, index 1 is address ptrarray + sizeof (ArrayType), etc, etc, etc.  I'm sure we've all done something similar in our own right at some point or another.

    So, Given THis setup:

    <StructLayout(LayoutKind.Sequential)> _
    Public Structure MyStruct
     <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=50> _
     Public Name as String
     Public Dimensions as SizeF
     Public Map as MapModeEnum
     Public structSize as Integer
     Public arrayCount as integer
     Public MyArr() as MyStruct2
    End Structure
    
    <StructLayout(LayoutKind.Sequential)> _
    Public Structure MyStruct2
     Public Enum1 as MyENum1
     Public Data as integer
     Public Factor as Single
    End Structure
    

    Now, Like I said, i'm saying I'm going to do this, but I'm curious, how would one marshal this structure from VB.Net across Win32 API lines.  Some times Win32 API calls have a callback, where one of the parameters is a pointer to a User object or type, same as many managed .Net events and delegates which have a similar feature.  However, I can't marshal an "Object" across the API lines back into the call back method.  Now if it was a simple structure, or string, I've already dealt with that kind of marshalling, so simple ptrtostructure, an allochglobal calls are not unknown to me, but i'm trying to figure out the wisest course of action for passing user data through an API callback. 

    I would also go so far as to say, that it is quite possible in this circumstance the the MyArr() field will need to be updated by the call back, but in a manner which the original IntPtr to MyStruct which was passed to the API call, needs to remain the same, as it most likely won't be changing.  which means, I could be doing a single AllocHGlobal call for the MyStruct, and have MyArr be an IntPtr that is assigned by call back.  it's all memory, so unless the Marshalling from .Net to API and back messes with allocated memory buffer data I should be fine, but again, as I said, it is a curiosity to me.  I like to know how. :)

    Thanks

    Jaeden "Sifo Dyas" al'Raec Ruiner


    "Never Trust a computer. Your brain is smarter than any micro-chip."
    PS - Don't mark answers on other people's questions. There are such things as Vacations and Holidays which may reduce timely activity, and until the person asking the question can test your answer, it is not correct just because you think it is. Marking it correct for them often stops other people from even reading the question and possibly providing the real "correct" answer.
    Friday, April 22, 2011 9:37 PM

All replies

  • Hello, in the unsafe code world of C# you can use stackalloc to allocate portions of the stack for a given struct type:
     
     public unsafe void MyUnsafeMethod()
     {
      DateTime* firstDateTimePointer = stackalloc DateTime[1024];
    
      // You can use pointer arithmetic here
      var secondDateTimePointer = firstDateTimePointer++;
     }
    
    
     
    To get more information about stackalloc you can visit the following URL:
    To get more information about unsafe code and pointers you can visit this other URL:
    Hope this helps,
    Miguel.
     
     


    Monday, April 25, 2011 1:31 PM
  • Ahh,

    Well I'll definitely look into stackalloc, but I am also trying to work within the confines of VB at the moment.  I've used C# frequently, but currently most of my code is in VB which the whole "unsafe" and "fixed" are not either not as versatile or in the case of fixed simply not present.  *sigh*

    Thanks though

    J"SD"a'RR


    "Never Trust a computer. Your brain is smarter than any micro-chip."
    PS - Don't mark answers on other people's questions. There are such things as Vacations and Holidays which may reduce timely activity, and until the person asking the question can test your answer, it is not correct just because you think it is. Marking it correct for them often stops other people from even reading the question and possibly providing the real "correct" answer.
    Monday, April 25, 2011 9:06 PM
  •  

    Hi,

     

    Well, in my opinion, structure is a ValueType in .NET world. I think it is not a good idea that use a valuetype as retrieve value from a method. This is because object of valuetype will be released after method being completed. Changed data won’t be showed to the retrieved valuetype.

     


    Paul Zhou [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, April 28, 2011 4:05 AM