|
Posted on
2004-07-05 23:32
hbiftsaa
阅读( 3249)
评论()
编辑
收藏
举报
在.NET中,进行程序间通信,可以使用的方法很多,比如.NET Remoting,WebService.等等.. 但是使用上述方法太过于麻烦.不是很轻便..
在Win32中,一般要完成上述功能,方法也很多,一个比较通用的方法就是直接使用内存映射文件.Mapping File. .NET FX1.0提供了P/Invoke,可能通过这个来直接调用Win32的API.这里我来演示一下这个方法.
要使用P/Invoke,我们得加入这个命名空间: System.Runtime.InteropServices 然后使用DllImportAttribute来导入我们所要用的Win32 API:
![](/Images/OutliningIndicators/ContractedBlock.gif) DllImport#region DllImport
[StructLayout(LayoutKind.Sequential)]
private struct SECURITY_ATTRIBUTES
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
int nLength;
int lpSecurityDescriptor;
bool bInheritHandle;
}
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("kernel32",CharSet = CharSet.Auto)]
private static extern int CreateFileMapping(
int hFile,
int lpSecurityAttributes,
int flProtect,
int dwMaximumSizeHigh,
int dwMaximumSizeLow,
[MarshalAs(UnmanagedType.LPTStr)] string lpName
);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("kernel32",CharSet = CharSet.Auto)]
private static extern int OpenFileMapping(
int dwDesiredAccess,
bool bInheritHandle,
[MarshalAs(UnmanagedType.LPTStr)] string lpName
);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("kernel32",CharSet = CharSet.Auto)]
private static extern bool UnmapViewOfFile(int lpBaseAddress);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("kernel32",CharSet = CharSet.Auto)]
private static extern void CloseHandle(int Handle);
![](/Images/OutliningIndicators/InBlock.gif)
[DllImport("kernel32",CharSet = CharSet.Auto)]
private static extern int MapViewOfFile(
int hFileMappingObject,
int dwDesiredAccess,
int dwFileOffsetHigh,
int dwFileOffsetLow,
int dwNumberOfBytesToMap
);
#endregion 由于原始的API使用到了多个Enum,我们也实现这些个Enum,以方便以后的使用.
![](/Images/OutliningIndicators/ContractedBlock.gif) Mapping File Enum Info#region Mapping File Enum Info
public enum ProtectionTypes:int
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
PageReadOnly = 0x2,
PageReadWrite = 0x4,
PageWriteCopy = 0x8
}
![](/Images/OutliningIndicators/InBlock.gif)
public enum SectionTypes:int
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
SecCommit = 0x8000000,
SecImage = 0x1000000,
SecNoCache = 0x10000000,
SecReserve = 0x4000000
}
![](/Images/OutliningIndicators/InBlock.gif)
public enum AccessTypes:int
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
Copy = 0x1,
Read = 0x4,
Write = 0x2,
Full = 0xF001F
}
#endregion 接下来,就是把这些函数进行封装了:) 这里,我把这些函数封装到一个Class中,其Class的定义如下:
![](/Images/OutliningIndicators/ContractedBlock.gif) SharedMemory#region SharedMemory
public class SharedMemory : IDisposable
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](/Images/OutliningIndicators/ContractedSubBlock.gif) Private & Public Variable#region Private & Public Variable
private const int INVALID_HANDLE_VALUE = -1;
private int hMap = INVALID_HANDLE_VALUE;
private int lpAddr = 0;
private int size;
private int length;
public int MapHandle
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) get {return hMap;}
}
public int Address
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) get {return lpAddr;}
}
![](/Images/OutliningIndicators/InBlock.gif)
public int Size
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) get { return size;}
}
![](/Images/OutliningIndicators/InBlock.gif)
public int Length
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) get { return length;}
}
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif) Constructor#region Constructor
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) public SharedMemory() {}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) public SharedMemory(int Size,string Name) : this( Size,Name,ProtectionTypes.PageReadWrite,SectionTypes.SecCommit,AccessTypes.Full) {}
public SharedMemory(int Size, string Name, ProtectionTypes Protection, SectionTypes Section, AccessTypes Access )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
Create(Size, Name, Protection, Section, Access);
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif) Common Function#region Common Function
public void Create( int Size,string Name)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
Create( Size,Name,ProtectionTypes.PageReadWrite,SectionTypes.SecCommit,AccessTypes.Full);
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Create( int Size, string Name,ProtectionTypes Protection, SectionTypes Section, AccessTypes Access)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
Dispose();
size = Size;
hMap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, (int)Protection|(int)Section, 0, Size, Name);
if(hMap ==0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
throw new ApplicationException("Can't Create MappingFile " + Name);
}
lpAddr = MapViewOfFile(hMap, (int)Access, 0, 0, Size);
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) public void Open(int Size, string Name) {this.Open(Size, Name, 0, AccessTypes.Read);}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) public void Open(int Size, string Name, AccessTypes Access) {this.Open(Size, Name, 0, Access);}
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) public void Open(int Size, string Name, int Offset) {this.Open(Size, Name, Offset, AccessTypes.Read);}
public void Open(int Size, string Name, int Offset, AccessTypes Access)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
size = Size;
hMap = OpenFileMapping((int)Access, false, Name);
if(hMap == 0)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
throw new ApplicationException("Can't Open MappingFile " + Name);
}
lpAddr = MapViewOfFile(hMap, (int)Access, 0, Offset, Size);
}
![](/Images/OutliningIndicators/InBlock.gif)
public void CopyFrom(byte[] source,int startIndex,int length)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
this.length = length;
Marshal.Copy(source,startIndex,new IntPtr(Address),length);
}
![](/Images/OutliningIndicators/InBlock.gif)
public void CopyFrom(byte[] source)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
CopyFrom(source,0,source.Length);
}
![](/Images/OutliningIndicators/InBlock.gif)
public void CopyFrom(string source)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
byte[] temp = Encoding.Unicode.GetBytes(source);
CopyFrom(temp,0,temp.Length);
}
![](/Images/OutliningIndicators/InBlock.gif)
public void CopyTo(byte[] destination,int startIndex,int length)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
Marshal.Copy( new IntPtr(Address),destination,startIndex,length);
}
![](/Images/OutliningIndicators/InBlock.gif)
public byte[] CopyToBytes()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
byte[] destination = new byte[Size];
CopyTo( destination,0,Size);
return destination;
}
![](/Images/OutliningIndicators/InBlock.gif)
public byte[] CopyToBytes(int startIndex,int length)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
byte[] destination = new byte[Size];
CopyTo( destination,startIndex,length);
return destination;
}
![](/Images/OutliningIndicators/InBlock.gif)
public string CopyToString(out string destination)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
destination = CopyToString();
return destination;
}
![](/Images/OutliningIndicators/InBlock.gif)
public string CopyToString()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
byte[] temp = new byte[Size];
CopyTo(temp,0,temp.Length);
return Encoding.Unicode.GetString(temp).Trim();
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Close()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
Dispose();
}
![](/Images/OutliningIndicators/InBlock.gif)
public void Dispose()
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
if( lpAddr != 0 )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
UnmapViewOfFile(lpAddr);
}
if( hMap != 0 && hMap != INVALID_HANDLE_VALUE )
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
CloseHandle(hMap);
}
}
#endregion
}
![](/Images/OutliningIndicators/InBlock.gif)
#endregion 注意: 加入上述DllImport函数. 通过这个方法,我们就可以直接使用MappingFile了. 示例代码如下:
![](/Images/OutliningIndicators/ExpandedBlockStart.gif) public void Test() {
SharedMemory sm = new SharedMemory();
sm.Create(1024,"hbifts");
sm.CopyFrom("hoho.i love cnblogs");
SharedMemory sm1 = new SharedMemory();
sm1.Open(1024,"hbifts");
Console.WriteLine(sm1.CopyToString());
} 到现在为止,关于Win32的MappingFile API就已封装好了~ 我们可以直接在.NET应用程序中使用了:) 下载 : SharedMemory注: 此代码参考于Gotdotnet上面的一个朋友的文章.
|