Мне нужно объединить некоторые вложенные структуры в C# 4.0 в двоичные капли, чтобы перейти к платформе C++.C# interop: плохое взаимодействие между фиксированным и MarshalAs
Я до сих пор имел большой успех, используя unsafe
/fixed
для обработки массивов фиксированной длины примитивных типов. Теперь мне нужно обработать структуру, содержащую вложенные массивы фиксированной длины других структур.
Я использовал сложные обходные решения, сглаживающие структуры, но затем я натолкнулся на пример атрибута MarshalAs
, который выглядел так, как будто это могло спасти мне массу проблем.
К сожалению, пока это дает мне правильный количество данных, кажется, также остановить fixed
массивы из того ранжированы правильно, так как выход из этой программы демонстрирует. Вы можете подтвердить сбой, поставив точку останова на последней строке и исследуя память на каждом указателе.
using System;
using System.Threading;
using System.Runtime.InteropServices;
namespace MarshalNested
{
public unsafe struct a_struct_test1
{
public fixed sbyte a_string[3];
public fixed sbyte some_data[12];
}
public struct a_struct_test2
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)]
public sbyte[] a_string;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public a_nested[] some_data;
}
public unsafe struct a_struct_test3
{
public fixed sbyte a_string[3];
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
public a_nested[] some_data;
}
public unsafe struct a_nested
{
public fixed sbyte a_notherstring[3];
}
class Program
{
static unsafe void Main(string[] args)
{
a_struct_test1 lStruct1 = new a_struct_test1();
lStruct1.a_string[0] = (sbyte)'a';
lStruct1.a_string[1] = (sbyte)'b';
lStruct1.a_string[2] = (sbyte)'c';
a_struct_test2 lStruct2 = new a_struct_test2();
lStruct2.a_string = new sbyte[3];
lStruct2.a_string[0] = (sbyte)'a';
lStruct2.a_string[1] = (sbyte)'b';
lStruct2.a_string[2] = (sbyte)'c';
a_struct_test3 lStruct3 = new a_struct_test3();
lStruct3.a_string[0] = (sbyte)'a';
lStruct3.a_string[1] = (sbyte)'b';
lStruct3.a_string[2] = (sbyte)'c';
IntPtr lPtr1 = Marshal.AllocHGlobal(15);
Marshal.StructureToPtr(lStruct1, lPtr1, false);
IntPtr lPtr2 = Marshal.AllocHGlobal(15);
Marshal.StructureToPtr(lStruct2, lPtr2, false);
IntPtr lPtr3 = Marshal.AllocHGlobal(15);
Marshal.StructureToPtr(lStruct3, lPtr3, false);
string s1 = "";
string s2 = "";
string s3 = "";
for (int x = 0; x < 3; x++)
{
s1 += (char) Marshal.ReadByte(lPtr1+x);
s2 += (char) Marshal.ReadByte(lPtr2+x);
s3 += (char) Marshal.ReadByte(lPtr3+x);
}
Console.WriteLine("Ptr1 (size " + Marshal.SizeOf(lStruct1) + ") says " + s1);
Console.WriteLine("Ptr2 (size " + Marshal.SizeOf(lStruct2) + ") says " + s2);
Console.WriteLine("Ptr3 (size " + Marshal.SizeOf(lStruct3) + ") says " + s3);
Thread.Sleep(10000);
}
}
}
Выход:
Ptr1 (size 15) says abc
Ptr2 (size 15) says abc
Ptr3 (size 15) says a
Так почему-то только сортировочных первый символ моих fixed
строк ANSI. Есть ли способ обойти это, или я сделал что-то глупое, не связанное с сортировкой?
Переполнение стека: получите репутацию для редактирования сообщений людей и плагиата документов MSDN. Задайте трудный вопрос? [Crickets] –
Вы по крайней мере получаете значок переползания;) И теперь с щедростью вы получите внимание лучшего разработчика *, но не нужно отношения *. –
Вы использовали этот сайт раньше? Он работает на плохое отношение. :-P –