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
- Allocate result with at least startIndex + structureSize bytes (use Marshal.SizeOf<T> or the structureSize you pass).
- Lower startIndex or split the write so the range fits within the existing buffer.
- 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
- Always size buffers from Marshal.SizeOf<T>() rather than hardcoded constants.
- Re-derive buffer sizes whenever a struct definition changes; add a unit test asserting buffer capacity.
- Reserve capacity once when building multi-struct packet buffers.
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
- Buffer length is not enough.
- Start index is invalid.
- Buffer is invalid.
- Resource manager is invalid.
- Data provider helper is invalid.
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)