2012-06-28 3 views
2

Я использую собственные функции и имею небольшую проблему с marshaling structs в C#. У меня есть указатель на структуру в другой структуре - например, C#:Marshaling in C# - передача указателя на ссылку структуры ("double ref"?)

[StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)] 
    public struct PARENT 
    { 
     [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
     public string Name; 
     [MarshalAs(UnmanagedType.Struct, SizeConst=8)] 
     public CHILD pChild; 
    } 

    [StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)] 
    public struct CHILD 
    { 
     public UInt32 val1; 
     public UInt32 val2; 
    } 

В структуре PARENT у меня должен быть указатель на структуру CHILD. Мне нужно передать «указатель на ссылку» (структуры PARENT) в качестве аргумента функции API.

Нет проблем с одиночной ссылкой («ref PARENT» в качестве аргумента импортированной функции dll), но как передать «ref ref»? Возможно ли использование небезопасного кода (с помощью C-указателя)?

поздравления Артур

+0

В чем проблема с 'ref parent.pChild'? – SimpleVar

+1

Объявите CHILD как класс вместо этого и удалите атрибут, вы получите бесплатный указатель. –

ответ

1

Если вы не хотите использовать небезопасный код, то вам нужно определить ребенка, как IntPtr и добавить свойство, доступ затем значения из детского IntPtr.

[StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)] 
public struct PARENT 
{ 
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] 
    public string Name; 
    public IntPtr pChild; 
    public CHILD Child{ 
     get { 
     return (CHILD)Marshal.PtrToStructure(pChild, typeof(CHILD)); 
     } 
    } 
} 

[StructLayout(LayoutKind.Sequential, Pack=1, CharSet = CharSet.Auto)] 
public struct CHILD 
{ 
    public UInt32 val1; 
    public UInt32 val2; 
} 

Я думаю, что это проще и чист с небезопасным кодом/указателями.

0

Это комбинация безопасного и небезопасного, так как я считаю здесь разумным.

fixed (void* pt = new byte[Marshal.SizeOf(myStructInstance)]) 
{ 
    var intPtr = new IntPtr(pt); 
    Marshal.StructureToPtr(myStructInstance, intPtr, true); 

    // now "pt" is a pointer to your struct instance 
    // and "intPtr" is the same, but wrapped with managed code 
} 
Смежные вопросы