EllanJiang/GameFramework · error · GameFrameworkException

Result length is not enough.

Error message

Result length is not enough.

What it means

After validating startIndex, StructureToBytes checks that the destination byte array has room for structureSize bytes starting at startIndex. If startIndex + structureSize exceeds result.Length, the library throws instead of letting the unmanaged copy overflow. The struct bytes are staged in a cached HGlobal buffer and copied via Marshal.Copy, which requires the destination range to fit exactly.

Solutions

  1. Allocate result with at least startIndex + structureSize bytes (use Marshal.SizeOf<T> or the structureSize you pass).
  2. Lower startIndex or split the write so the range fits within the existing buffer.
  3. Recheck struct size after any struct field changes and update buffer-size constants.

Example fix

// before
byte[] dest = new byte[16]; // too small after struct grew
Utility.Marshal.StructureToBytes(header, Marshal.SizeOf<Header>(), dest, 0);
// after
int size = Marshal.SizeOf<Header>();
byte[] dest = new byte[size];
Utility.Marshal.StructureToBytes(header, size, dest, 0);
Defensive patterns

Strategy: validation

Validate before calling

int needed = startIndex + structureSize;
if (result == null || result.Length < needed)
    result = new byte[needed];
Utility.Marshal.StructureToBytes(structure, structureSize, result, startIndex);

Try / catch

try
{
    Utility.Marshal.StructureToBytes(structure, size, dest, offset);
}
catch (GameFrameworkException ex) when (ex.Message == "Result length is not enough.")
{
    dest = new byte[offset + size];
    Utility.Marshal.StructureToBytes(structure, size, dest, offset);
}

Prevention

When it happens

Trigger: Calling Utility.Marshal.StructureToBytes where result.Length < startIndex + structureSize — e.g. a too-small byte array allocated for a smaller struct, or writing a large struct at a nonzero offset in a fixed-size buffer.

Common situations: Struct definition grew (added fields) but the destination buffer size constant was not updated; writing multiple structs sequentially into a packet buffer and running past the end; wrong sizeof estimate for a struct with Blittable/unicode fields.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of EllanJiang/GameFramework@d0c010b051 (2026-09-15). Data as JSON: /api/errors/68433d82ef923ba1. Report an issue: GitHub.

Appendix: source

Thrown at GameFramework/Utility/Utility.Marshal.cs:161

            {
                if (structureSize < 0)
                {
                    throw new GameFrameworkException("Structure size is invalid.");
                }

                if (result == null)
                {
                    throw new GameFrameworkException("Result is invalid.");
                }

                if (startIndex < 0)
                {
                    throw new GameFrameworkException("Start index is invalid.");
                }

                if (startIndex + structureSize > result.Length)
                {
                    throw new GameFrameworkException("Result length is not enough.");
                }

                EnsureCachedHGlobalSize(structureSize);
                System.Runtime.InteropServices.Marshal.StructureToPtr(structure, s_CachedHGlobalPtr, true);
                System.Runtime.InteropServices.Marshal.Copy(s_CachedHGlobalPtr, result, startIndex, structureSize);
            }

            /// <summary>
            /// 将数据从二进制流转换为对象。
            /// </summary>
            /// <typeparam name="T">要转换的对象的类型。</typeparam>
            /// <param name="buffer">要转换的二进制流。</param>
            /// <returns>存储转换结果的对象。</returns>
            public static T BytesToStructure<T>(byte[] buffer)
            {
                return BytesToStructure<T>(System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)), buffer, 0);
            }

View on GitHub (pinned to d0c010b051)