Problems in Marshal.PtrToStructure

Hi all,

I'm having problems when using Marshal.PtrToStructure and passing a structure type to it with structure array as one of its members.

The exception i'm getting is
'
can not marshal field ComnPara of type DeviceDialog.CgfFileStruct
This type cannot be marshaled as a structure filed.
'

This is my structure

 [StructLayout(LayoutKind.Sequential)] public struct CfgFileStruct
{
 [MarshalAs(UnmanagedType.ByValArray,SizeConst=Constants.MAX_PORTS - 1 )] public ComnParaStruct[] ComnPara; [MarshalAs(UnmanagedType.ByValArray,SizeConst=Constants.MAX_PORTS -1 )]
 public long[] wNumOfUnits;
[MarshalAs(UnmanagedType.Struct)]
public UnitAdrsStruct UnitAdrs;
public long CRCCheckSum;
}



and this is my line fo code using Marshal.PtrToStructure

   

_CfgMap = (CfgFileStruct)Marshal.PtrToStructure(iCfgMap,typeof(CfgFileStruct));
 
  

Here when i use ComnParaStruct as a array i'm getting this exception.I tried all the other types of Marshal options.But i can able to pass a struct object (UnitAdrsStruct) and Array Object(wNumOfUnits) successfully.The problem only comes when passing Array of Struct as Parameter.

Please give any suggestions..

Thanks,
Suresh.





Answer this question

Problems in Marshal.PtrToStructure

  • Michal Levy

    Well
    the idea is just use byte[] with the right size in your struct
    then get the address of the original allocated instance of struct
    pin it get the IntPtr
    and use Marshal.Copy to get he data from your mashaling struct byte[] array.

    for intro to using such allocations:
    http://www.codeproject.com/vb/net/Marshal.asp

    Sure you can go manually and use shifting in order to adjust 4bytes in a single float for example.

  • Eva DELORD

    Sorry for the slow response Suresh.
    Unfortunately marshalling arrays of structures is not supported in V1.1.  We have added support for this in V2.0 and I just verified that your scenario does indeed work using VS 2005 Beta 2.

    It's a little awkward, but you should be able to work around this limitation by marshalling ComnPara into a byte array, and then looping through the array and copying each element out into a structure (using Marshal.PtrToStructure again) which you build up and place into a new array.

    I hope this helps, sorry there isn't a simpler answer :-)
       Rick

  • James Relyea

    Is my question not clear Or i've to post this question in some other Sections like C#

    Please help..

    Suresh.

  • George.Saliba

    Rick,

    Thanks for your answer.Actually i was struggling and started confusing whether it was possible or not.Now its clear.

    Can you give some more information on how can i do that alternative method..ie Marshalling as Byte array and looping...

    Thanks,
    Suresh.

  • question mark

    Hi Friends Smile

    Could anyone please help me to resolve following issue where I need to pass an array of structures to dll built in VC++ 6.0 :

    Structure Declaration:

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)> Public Structure tree_struct
    Dim level As Short
    Dim branch_id As String
    Dim s_desc As String
    Dim parent_id As String
    Dim access As Short
    Dim flag As Short
    Dim branch_desc As String
    End Structure


    DLL method Declaration :

    Public Class LibWrap
    Declare Function fetch_tree_hierarchy Lib "tcvbodss.dll" (ByVal mnu_handle As Short, ByVal apl_id As String, ByRef outArray As IntPtr) As Short
    End Class


    VB Code :

    Dim outArray As IntPtr
    LibWrap.vb_get_menu_hierarchy(tree_handle, "app_id", l_tree_struct)
    Dim manArray(100) As vb_menu
    Dim current As IntPtr = outArray
    Dim i As Integer

    For i = 0 To 100 - 1

    manArray(i) = New tree_struct

    Marshal.PtrToStructure(current, manArray(i))

    Marshal.DestroyStructure(current, GetType(tree_struct))

    current = IntPtr.op_Explicit(current.ToInt64() + Marshal.SizeOf(manArray(i)))

    Console.WriteLine("Element {0}: {1} {2}", i, manArray(i).branch_id, manArray(i).branch_desc)

    Next i

    Marshal.FreeCoTaskMem(outArray)

    At line : " Marshal.PtrToStructure(current, manArray(i))" I am getting following exception :

    Message : Value cannot be null.
    Parameter name: ptr

    My mistake may be quite silly as I am new to VB 2005 , kindly help me to resolve this problem.

    Sincerely,

    Sudhansu

  • Problems in Marshal.PtrToStructure