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++库函数返回的数据上。

新的代码:

ExpandedBlockStart.gif 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)

代码:

 

ExpandedBlockStart.gif 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;
            }
        }

 

转载于:https://www.cnblogs.com/bandik/archive/2011/10/25/2224243.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值