C#操作内存实例详解

ericwuhk 2009-08-20

C# 操作内存是如何实现的呢?让我们开始讲解吧:

我们先来看看C#中如何操作内存,也就是非托管的数据。这需要引用System.Runtime.InteropServices命名空间。该命名空间下的Marshal的一些静态方法提供了这样的功能:

Marshal.ReadInt32()  



//从指定内存地址读取4位 C#操作内存  



Marshal.PtrToStringAnsi()  



//从指定内存地址读取字符串C#操作内存   



Marshal.WriteInt32()  



//将整数写到指定内存地址 C#操作内存  



Marshal.WriteByte()  



//将字符串写到指定内存地址我们来看看具体的代码:   




using System;   




using System.Text;   




using System.Runtime.InteropServices;   



 



internal sealed class RCEvent {   




public int Event;   




public int Flag;   




public string User;   



};   


 //C#操作内存



internal sealed class RCEventAgent {   




internal static RCEvent Read(IntPtr ptr){   




RCEvent Event = new RCEvent();   



   


Event.Event = ReadEvent(ptr);   


Event.Flag = ReadFlag(ptr);   


Event.User = ReadUser(ptr);   


 



return Event;   



}   


 //C#操作内存



internal static int ReadEvent(IntPtr basePtr) {   




return Marshal.ReadInt32(basePtr);   



}   



internal static int ReadFlag(IntPtr basePtr) {   




return Marshal.ReadInt32(basePtr,4);   



}   



internal static string ReadUser(IntPtr basePtr) {   




return Marshal.PtrToStringAnsi(  




new IntPtr(basePtr.ToInt32() + 8));   



}   


 



internal static void Write(ClientEvent Event,IntPtr ptr) {   



WriteEvent(ptr,Event.Event);   


WriteFlag(ptr,Event.Flag);   


WriteUser(ptr,Event.User);   


}   


 //C#操作内存



internal static void WriteEvent(  




IntPtr basePtr,int value) {   



Marshal.WriteInt32(basePtr,value);   


}   



internal static void WriteFlag(  




IntPtr basePtr,int flag) {   



Marshal.WriteInt32(basePtr,4,flag);   


}   



internal static void WriteUser(  




IntPtr basePtr,string user) {   



WriteString(basePtr,user,8,40);   


}   



private static void WriteString(  




IntPtr basePtr,string value,int offset,int length) {   




int pos = 0;   




byte[] bytes = Encoding.Default.GetBytes(value);   




while(pos  length) {   




if (pos  bytes.Length)   



Marshal.WriteByte(basePtr,offset,bytes[pos]);   



else   



Marshal.WriteByte(basePtr,offset,0);   


 


pos ++;   


offset ++;   


}   


}   //C#操作内存


} 

这样我们就可以通过ReadEvent和WriteEvent直接在c#中处理该结构体。或者通过 ReadXXX() 和 WriteXXX() 直接修改其字段。

public void DoSomething(IntPtr ptr){   


RCEvent Event = RCEventAgent.Read(ptr);   


Event.Flag ++;   


RCEventAgent.Write(ptr, Event);   


 



// 或者以下代码   




// RCEventAgent.WriteFlag( ptr, RCEventAgent.ReadFlag(ptr) + 1 );   



} 

C++中则可以直接将结构体地址传给C#:

相关推荐