bandik

 

C#获取64位系统内存和 CSC编译的access violation错误

有如下的程序段(GetTotalMem.cs):

 

using System;
using System.IO;
using System.Runtime.InteropServices;

namespace fdx
{
    public struct MemoryStatus 
    { 
        public uint Length;  
        public uint MemoryLoad; 
        public uint TotalPhysical; 
        public uint AvailablePhysical; 
        public uint TotalPageFile; 
        public uint AvailablePageFile; 
        public uint TotalVirtual;
        public uint AvailableVirtual;
    }

    public class Program
    {
        [DllImport("kernel32.dll")] 
        public static extern void GlobalMemoryStatus(out MemoryStatus stat);

        public static void Main()
        {
            MemoryStatus stat = new MemoryStatus();
            GlobalMemoryStatus(out stat);
            uint ram = stat.TotalPhysical;
            Console.WriteLine(ram);
            Console.ReadKey();
        }

    }

}

在64位机器上用命令

csc GetTotalMem.cs

编译后的程序运行在输入key时总会出错,说程序停止工作。

而用在命令行先后加上/debug标识,则又一切OK。

 

现在转回去,指定编译平台为

csc GetTotalMem.cs /platform:x86

则运行正常。

指定编译平台为

csc GetTotalMem.cs /platform:x64

继续出错。然后再加上/debug标识,又正常。

Visual Studio 下的项目倒是一切正常,不知道是什么地方又藏着一个问题,先写到这里,看看以后有没有更新的发现。

 ---------------------------------------------------华丽的日期分隔线-----------------------------------------------------------

昨天的代码经过研究,发现问题出在C#调用C++的库的时候的引用方式以及结构定义的数据不能容纳C++库函数返回的数据上。

新的代码:

View Code
using System;
using System.IO;
using System.Runtime.InteropServices;

namespace fdx
{
    [StructLayout(LayoutKind.Sequential)]
    public struct MEMORYSTATUSEX
    {
        public uint dwLength;
        public uint dwMemoryLoad;
        public ulong ullTotalPhys;
        public ulong ullAvailPhys;
        public ulong ullTotalPageFile;
        public ulong ullAvailPageFile;
        public ulong ullTotalVirtual;
        public ulong ullAvailVirtual;
        public ulong ullAvailExtendedVirtual;
    }
    [StructLayout(LayoutKind.Sequential)]
public struct MemoryStatus 
    { 
        public uint Length;  
        public uint MemoryLoad; 
        public ulong TotalPhysical; 
        public ulong AvailablePhysical; 
        public ulong TotalPageFile; 
        public ulong AvailablePageFile; 
        public ulong TotalVirtual;
        public ulong AvailableVirtual;
    }


    public class Program
    {
        [DllImport("kernel32.dll")]
        public static extern void GlobalMemoryStatusEx(ref MEMORYSTATUSEX stat); 

        [DllImport("kernel32.dll")] 
        public static extern void GlobalMemoryStatus(ref MemoryStatus stat);
        

        public static void Main()
        {
            MEMORYSTATUSEX stat =new MEMORYSTATUSEX();
            stat.dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));

            GlobalMemoryStatusEx(ref stat);
            long ram = (long)stat.ullAvailPhys/1024/1024;
            Console.WriteLine(stat.ullAvailPhys/1024/1024);
            Console.WriteLine(stat.ullTotalPhys / 1024 / 1024);
            Console.WriteLine(stat.ullTotalVirtual / 1024 / 1024/1024);
            //Console.ReadKey();
            MemoryStatus stat2 = new MemoryStatus();
            stat2.Length=(uint)Marshal.SizeOf(typeof(MemoryStatus));
            GlobalMemoryStatus(ref stat2);
            Console.WriteLine(stat2.AvailablePhysical/1024/1024);
        
        }
    }

}

 

现在问题解决。debug方式会为我们屏蔽掉很多越界异常,所以在VS2010下虽然结果不对,但是还是正确退出。

顺便提供另外一个获取内存信息的方法( WMI)

代码:

 

View Code
    /// <summary>
    
/// 内存类
    
/// </summary>
    public class Memory
    {
        private string _totalMem;
        private string _availMem;
        private string _usageRate;


        /// <summary>
        
/// 内存使用率
        
/// </summary>
        public string UsageRate
        {
            get { return _usageRate; }
            set { _usageRate = value; }
        }
        /// <summary>
        
/// 总可用内存的大小
        
/// </summary>
        public string AvailMem
        {
            get { return _availMem; }
            set { _availMem = value; }
        }
        /// <summary>
        
/// 总物理内存的大小
        
/// </summary>
        public string TotalMem
        {
            get { return _totalMem; }
            set { _totalMem = value; }
        }

   }
        public static  bool ReadMemory(Memory memory)
        {
            try
            {
                #region 内存使用情况

                double totalMem = 0.0;
                double AvailMem = 0.0;
                //计算物理内存 
                ManagementObjectSearcher search = new ManagementObjectSearcher("Select * from Win32_PhysicalMemory");
                int i = 0;
                ManagementObjectCollection infos = search.Get();
                foreach (ManagementObject info in infos)
                {
                    i = i + 1;
                    totalMem += Convert.ToDouble(info["Capacity"].ToString()) / 1024/1024;
                }
                memory.TotalMem = totalMem.ToString();
                //计算剩余内存
                search = new ManagementObjectSearcher("Select AvailableMBytes from Win32_PerfRawData_PerfOS_Memory");
                i = 0;
                foreach (ManagementObject info in search.Get())
                {
                    i = i + 1;
                    AvailMem += Convert.ToDouble(info["AvailableMBytes"].ToString());
                }
                memory.AvailMem = AvailMem.ToString();
                memory.UsageRate = string.Format("{0}", Convert.ToDouble((1 - AvailMem / totalMem) * 100));
                #endregion
                return true;
            }
            catch(Exception e)
            {
                Console.WriteLine(e.Message);
                return false;
            }
        }

 

posted on 2011-10-25 17:59  五洋  阅读(1689)  评论(0编辑  收藏  举报

导航