You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#值传递与引用传递疑问:System.OverflowException异常排查

解决System.OverflowException与C#值/引用传递的误区

C#与Java的对象传递逻辑对比

  • Java里所有参数都是值传递:对象类型传递的是引用的副本(栈中存储堆地址的拷贝),这和C#中引用类型(class)的默认传递逻辑完全一致。
  • C#里的引用类型默认也是值传递(传递引用的副本),副本指向的是同一个堆对象,和Java没有本质区别。只有当需要让方法修改原引用本身时,才需要用ref或out关键字。你当前的useSummary方法参数传递逻辑没有问题,不是导致溢出的原因。

定位System.OverflowException的真实原因

错误明确触发在IntPtr basePointer = (IntPtr) summary.MainModuleBase;这一行,核心是数值类型转换时的范围溢出:

  • 32位进程中,IntPtr是4字节,最大值为0x7FFFFFFF(约2GB),如果summary.MainModuleBase存储的是64位进程的模块基地址(通常超过2GB),强制转换为32位IntPtr就会触发溢出。
  • 即使是64位进程,如果MainModuleBase是负数或超出IntPtr合法范围的数值,也会引发该错误。

具体解决方案

  1. 调整项目平台目标:
    如果你的程序是32位编译,但目标处理的是64位进程,直接将项目的平台目标改为x64,或者设为Any CPU并取消勾选“首选32位”选项,这样IntPtr会适配64位地址范围。

  2. 安全转换数值到IntPtr:
    避免直接强制转换,先做范围检查再转换:

    public bool useSummary(Summary summary, out PEFile outputFile)
    {
        outputFile = default(PEFile);
        // 检查当前进程位数与地址范围的兼容性
        if (IntPtr.Size == 4 && summary.MainModuleBase > int.MaxValue)
        {
            // 处理32位进程无法访问64位地址的场景,比如返回错误提示
            return false;
        }
        IntPtr basePointer = new IntPtr(summary.MainModuleBase);
        IMAGE_DOS_HEADER dosHeader = ReadProcessStruct<IMAGE_DOS_HEADER>(summary.ProcessId, basePointer);
        // 后续逻辑
        return true;
    }
    
  3. 确认MainModuleBase的类型定义:
    检查Summary类中MainModuleBase的类型,如果是ulong(无符号64位整数),在32位环境下需要确保其值不超过int.MaxValue,否则必须切换到64位平台运行。

内容的提问来源于stack exchange,提问作者UnSure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 07:09:53