Строка фиксированной длины в качестве типа значения для использования в MemoryMappedViewAccessor - PullRequest
3 голосов
/ 15 сентября 2011

Я хотел бы сохранить структуру в MemoryMappedFile, но эта структура содержит строки (с максимальным размером, который я знаю), которые являются ссылочным типом и поэтому отклоняются MemoryMappedViewAccessor.

Знаете ли вы хорошийСтроковая структура фиксированной длины (тип значения) реализация?Я могу жестко запрограммировать длину, если это необходимо (поскольку массивы являются ссылочными типами).

Например, я мог бы создать его экземпляр как:

TenCharsString myString = new TenCharsString("1234567890");

Украшение атрибутом MarshalAs

<MarshalAs (UnmanagedType.ByValTStr, SizeConst:=128)> 

должно работать, но это не так.

Ответы [ 2 ]

1 голос
/ 15 сентября 2011

Вот простой 10-символьный тип значения:

struct TenChars
{
    public char A;
    public char B;
    public char C;
    public char D;
    public char E;
    public char F;
    public char G;
    public char H;
    public char I;
    public char J;
}

Если опция небезопасного кода, это также работает:

unsafe struct TenChars
{
    public fixed char Chars[10];
}

Полный код:

struct TenChars1
{
    public const int Capacity = 10;

    private char A;
    private char B;
    private char C;
    private char D;
    private char E;
    private char F;
    private char G;
    private char H;
    private char I;
    private char J;

    public TenChars1(string value)
    {
        if (value == null) throw new ArgumentNullException("value");
        if (value.Length > Capacity) throw new ArgumentException();

        A = (value.Length > 0) ? value[0] : '\0';
        B = (value.Length > 1) ? value[1] : '\0';
        C = (value.Length > 2) ? value[2] : '\0';
        D = (value.Length > 3) ? value[3] : '\0';
        E = (value.Length > 4) ? value[4] : '\0';
        F = (value.Length > 5) ? value[5] : '\0';
        G = (value.Length > 6) ? value[6] : '\0';
        H = (value.Length > 7) ? value[7] : '\0';
        I = (value.Length > 8) ? value[8] : '\0';
        J = (value.Length > 9) ? value[9] : '\0';
    }

    public override string ToString()
    {
        return new string(new char[] { A, B, C, D, E, F, G, H, I, J });
    }
}

unsafe struct TenChars2
{
    public const int Capacity = 10;

    private fixed char buffer[Capacity];

    public TenChars2(string value)
    {
        if (value == null) throw new ArgumentNullException("value");
        if (value.Length > Capacity) throw new ArgumentException();

        fixed (char* ptr = this.buffer)
        fixed (char* chars = value)
        {
            for (int i = 0; i < value.Length; i++)
            {
                *(ptr + i) = *(chars + i);
            }
        }
    }

    public override string ToString()
    {
        fixed (char* ptr = this.buffer)
        {
            return new string(ptr);
        }
    }
}
0 голосов
/ 15 сентября 2011

Вы можете хранить внутреннюю структуру struct индивидуально.Вы можете хранить строки как массивы символов, используя WriteArray и ReadArray .Другие могут использовать различные методы записи .

...