EllanJiang/GameFramework · error · GameFrameworkException

Structure size is invalid.

Error message

Structure size is invalid.

What it means

Utility.Marshal.StructureToBytes<T>(T, int) validates structureSize before using the cached unmanaged buffer. A negative size would produce an invalid allocation and array, so the library throws immediately. This is an internal overload; callers normally use the public wrapper that supplies Marshal.SizeOf automatically.

Solutions

  1. Always pass Marshal.SizeOf<T>(structure) (or Utility.Marshal.SizeOf<T>()) as structureSize
  2. Use the public StructureToBytes<T>(T) overload that computes the size itself
  3. Validate any externally sourced size value before calling

Example fix

// before
Utility.Marshal.StructureToBytes(s, untrustedSize); // may be negative
// after
int size = Utility.Marshal.SizeOf(s);
byte[] bytes = Utility.Marshal.StructureToBytes(s, size);
Defensive patterns

Strategy: validation

Validate before calling

if (structureSize < 0) structureSize = Utility.Marshal.SizeOf(structure);

Type guard

bool IsValidStructureSize(int size) => size >= 0;

Prevention

When it happens

Trigger: Calling the internal overload StructureToBytes(structure, structureSize) with a negative size, typically from a buggy size computation or corrupted external size value.

Common situations: Custom serialization code caching a wrong size; sizes read from untrusted data streams used directly.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

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

            /// <param name="structure">要转换的对象。</param>
            /// <returns>存储转换结果的二进制流。</returns>
            public static byte[] StructureToBytes<T>(T structure)
            {
                return StructureToBytes(structure, System.Runtime.InteropServices.Marshal.SizeOf(typeof(T)));
            }

            /// <summary>
            /// 将数据从对象转换为二进制流。
            /// </summary>
            /// <typeparam name="T">要转换的对象的类型。</typeparam>
            /// <param name="structure">要转换的对象。</param>
            /// <param name="structureSize">要转换的对象的大小。</param>
            /// <returns>存储转换结果的二进制流。</returns>
            internal static byte[] StructureToBytes<T>(T structure, int structureSize)
            {
                if (structureSize < 0)
                {
                    throw new GameFrameworkException("Structure size is invalid.");
                }

                EnsureCachedHGlobalSize(structureSize);
                System.Runtime.InteropServices.Marshal.StructureToPtr(structure, s_CachedHGlobalPtr, true);
                byte[] result = new byte[structureSize];
                System.Runtime.InteropServices.Marshal.Copy(s_CachedHGlobalPtr, result, 0, structureSize);
                return result;
            }

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

View on GitHub (pinned to d0c010b051)