📄 marshalex.cs
字号:
//==========================================================================================
//
// OpenNETCF.Runtime.InteropServices.MarshalEx
// Copyright (c) 2003-2005, OpenNETCF.org
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the OpenNETCF.org Shared Source License.
//
// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the OpenNETCF.org Shared Source License
// for more details.
//
// You should have received a copy of the OpenNETCF.org Shared Source License
// along with this library; if not, email licensing@opennetcf.org to request a copy.
//
// If you wish to contact the OpenNETCF Advisory Board to discuss licensing, please
// email licensing@opennetcf.org.
//
// For general enquiries, email enquiries@opennetcf.org or visit our website at:
// http://www.opennetcf.org
//
//==========================================================================================
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace OpenNETCF.Runtime.InteropServices
{
/// <summary>
/// Provides a collection of methods for allocating unmanaged memory, copying unmanaged memory blocks, and converting managed to unmanaged types, as well as other miscellaneous methods used when interacting with unmanaged code.
/// </summary>
public sealed class MarshalEx
{
//don't allow constructor to be called - all static methods
private MarshalEx(){}
#region Fields
private const int GMEM_FIXED = 0x0000;
private const int LMEM_MOVEABLE = 2;
private const int LMEM_ZEROINIT = 0x0040;
private const int LPTR = (GMEM_FIXED | LMEM_ZEROINIT);
private static readonly int HIWORDMASK = -65536;//new IntPtr((long)-65536);
/// <summary>
/// Represents the default character size on the system; the default is 2 for Unicode systems and 1 for ANSI systems. This field is read-only.
/// </summary>
public static readonly int SystemDefaultCharSize = Marshal.SystemDefaultCharSize;
#endregion
#region Read functions
#region IntPtr
/// <summary>
/// Reads an IntPtr from an unmanaged pointer.
/// </summary>
/// <param name="ptr">The address in unmanaged memory from which to read. </param>
/// <param name="ofs">The offset from the ptr where the IntPtr is located.</param>
/// <returns>The IntPtr read from the ptr parameter. </returns>
public static IntPtr ReadIntPtr(IntPtr ptr, int ofs)
{
int i = Marshal.ReadInt32(ptr,ofs);
return new IntPtr(i);
}
#endregion
#region Int32
/// <summary>
/// Reads an Int32 object from an unmanaged pointer.
/// </summary>
/// <param name="ptr">The address in unmanaged memory from which to read. </param>
/// <param name="ofs">The offset from the ptr where the Int32 is located.</param>
/// <returns>The Int32 read from the ptr parameter. </returns>
public static Int32 ReadInt32(IntPtr ptr, int ofs)
{
return Marshal.ReadInt32(ptr, ofs);
/*byte[] data = new byte[4];
Marshal.Copy(new IntPtr(ptr.ToInt32() + ofs), data, 0, 4);
return BitConverter.ToInt32(data,0);*/
}
/// <summary>
/// Reads a 32-bit unsigned integer from unmanaged memory.
/// </summary>
/// <param name="ptr">The base address in unmanaged memory from which to read.</param>
/// <param name="ofs">An additional byte offset, added to the ptr parameter before reading.</param>
/// <returns>The 32-bit unsigned integer read from the ptr parameter.</returns>
[CLSCompliant(false)]
public static UInt32 ReadUInt32(IntPtr ptr, int ofs)
{
byte[] data = new byte[4];
Marshal.Copy(new IntPtr(ptr.ToInt32() + ofs), data, 0, 4);
return BitConverter.ToUInt32(data,0);
}
#endregion
#region Int16
/// <summary>
/// Reads a Int16 from an unmanaged pointer.
/// </summary>
/// <param name="ptr">The address in unmanaged memory from which to read. </param>
/// <param name="ofs">The offset from the ptr where the Int16 is located.</param>
/// <returns>The Int16 read from the ptr parameter. </returns>
public static Int16 ReadInt16(IntPtr ptr, int ofs)
{
return Marshal.ReadInt16(ptr, ofs);
/*byte[] data = new byte[2];
Marshal.Copy(new IntPtr(ptr.ToInt32() + ofs), data, 0, 2);
return BitConverter.ToInt16(data,0);*/
}
/// <summary>
///
/// </summary>
/// <param name="ptr"></param>
/// <param name="ofs"></param>
/// <returns></returns>
[CLSCompliant(false)]
public static UInt16 ReadUInt16(IntPtr ptr, int ofs)
{
byte[] data = new byte[2];
Marshal.Copy(new IntPtr(ptr.ToInt32() + ofs), data, 0, 2);
return BitConverter.ToUInt16(data,0);
}
#endregion
#region String
/// <summary>
/// Reads a string from an unmanaged pointer.
/// </summary>
/// <param name="ptr">The address in unmanaged memory from which to read. </param>
/// <param name="ofs">The offset from the ptr where the string is located.</param>
/// <param name="len">Length in characters.</param>
/// <returns>The string read from the ptr parameter. </returns>
public static string PtrToStringUni(IntPtr ptr, int ofs, int len)
{
int cb = len * Marshal.SystemDefaultCharSize;
byte[] data = new byte[cb];
Marshal.Copy(new IntPtr(ptr.ToInt32() + ofs), data, 0, cb);
string s = Encoding.Unicode.GetString(data, 0, len);
int nullpos = s.IndexOf('\0');
if(nullpos > -1)
s = s.Substring(0,nullpos);
return s;
}
/// <summary>
/// Allocates a managed System.String, copies a specified number of characters from an unmanaged ANSI string into it, and widens each ANSI character to Unicode.
/// </summary>
/// <param name="ptr">The address of the first character of the unmanaged string.</param>
/// <param name="ofs"></param>
/// <param name="len">The byte count of the input string to copy.</param>
/// <returns>A managed System.String that holds a copy of the native ANSI string.</returns>
public static string PtrToStringAnsi(IntPtr ptr, int ofs, int len)
{
int cb = len;
byte[] data = new byte[cb];
Marshal.Copy(new IntPtr(ptr.ToInt32() + ofs), data, 0, cb);
string s = Encoding.ASCII.GetString(data, 0, len);
int nullpos = s.IndexOf('\0');
if(nullpos > -1)
s = s.Substring(0,nullpos);
return s;
}
/// <summary>
/// Copies all characters up to the first null from an unmanaged ANSI string to a managed System.String. Widens each ANSI character to Unicode.
/// <para><b>New in v1.1</b></para>
/// </summary>
/// <param name="ptr">The address of the first character of the unmanaged string.</param>
/// <returns>A managed <see cref="T:System.String"/> object that holds a copy of the unmanaged ANSI string.</returns>
public static string PtrToStringAnsi(IntPtr ptr)
{
string returnval = "";
byte thisbyte = 0;
int offset = 0;
//while more chars to read
while(true)
{
//read current byte
thisbyte = Marshal.ReadByte(ptr, offset);
//if not null
if(thisbyte == 0)
{
break;
}
//add the character
returnval += ((char)thisbyte).ToString();
//move to next position
offset++;
}
return returnval;
}
/// <summary>
/// Allocates a managed System.String and copies all characters up to the first null character from an unmanaged Unicode string into it.
/// </summary>
/// <param name="ptr">The address of the first character of the unmanaged string.</param>
/// <returns>A managed string holding a copy of the native string.</returns>
public static string PtrToStringUni(IntPtr ptr)
{
return Marshal.PtrToStringUni(ptr);
}
/// <summary>
/// Allocates a managed <see cref="T:System.String"/> and copies all characters up to the first null character from a string stored in unmanaged memory into it.
/// <para><b>New in v1.1</b></para>
/// </summary>
/// <param name="ptr">The address of the first character.</param>
/// <returns>A managed string that holds a copy of the unmanaged string.</returns>
public static string PtrToStringAuto(IntPtr ptr)
{
if(ptr==IntPtr.Zero)
{
return null;
}
else
{
//final string value
string returnval = "";
//read first byte
int firstbyte = Marshal.ReadByte(ptr, 0);
//read second byte
int secondbyte = Marshal.ReadByte(ptr, 1);
//if first byte is non-zero continue
if(firstbyte!=0)
{
//if second byte is zero we may have unicode or one byte string
if(secondbyte==0)
{
//read third byte
int thirdbyte = Marshal.ReadByte(ptr, 2);
//if third byte is null this is a single byte string
if(thirdbyte==0)
{
//single ascii char
returnval = ((char)firstbyte).ToString();
}
else
{
//read unicode
return Marshal.PtrToStringUni(ptr);
}
}
else
{
//else appears to be ASCII
return PtrToStringAnsi(ptr);
}
}
return returnval;
}
}
#endregion
#region Char
/// <summary>
/// Reads a single char from an unmanaged pointer.
/// </summary>
/// <param name="ptr">The address in unmanaged memory from which to read. </param>
/// <param name="ofs">The offset from the ptr where the char is located.</param>
/// <returns>The char read from the ptr parameter. </returns>
public static char ReadChar(IntPtr ptr, int ofs)
{
byte[] data = new byte[Marshal.SystemDefaultCharSize];
Marshal.Copy(new IntPtr(ptr.ToInt32() + ofs),data, 0, data.Length);
return BitConverter.ToChar(data,0);
}
#endregion
#region Byte[]
/// <summary>
/// Reads a byte array from an unmanaged pointer.
/// </summary>
/// <param name="ptr">The address in unmanaged memory from which to read. </param>
/// <param name="ofs">The offset from the ptr where the byte array is located.</param>
/// <returns>The byte array read from the ptr parameter. </returns>
public static byte[] ReadByteArray(IntPtr ptr, int ofs, int len)
{
byte[] data = new byte[len];
Marshal.Copy(new IntPtr(ptr.ToInt32() + ofs), data, 0, len);
return data;
}
#endregion
#region Int64
/// <summary>
/// Reads an Int64 object from an unmanaged pointer.
/// </summary>
/// <param name="ptr">The address in unmanaged memory from which to read. </param>
/// <param name="ofs">The offset from the ptr where the Int64 is located.</param>
/// <returns>The Int64 read from the ptr parameter. </returns>
public static Int64 ReadInt64(IntPtr ptr, int ofs)
{
byte[] data = new byte[8];
Marshal.Copy(new IntPtr(ptr.ToInt32() + ofs), data, 0, 8);
return BitConverter.ToInt64(data,0);
}
/// <summary>
///
/// </summary>
/// <param name="ptr"></param>
/// <param name="ofs"></param>
/// <returns></returns>
[CLSCompliant(false)]
public static UInt64 ReadUInt64(IntPtr ptr, int ofs)
{
byte[] data = new byte[8];
Marshal.Copy(new IntPtr(ptr.ToInt32() + ofs), data, 0, 8);
return BitConverter.ToUInt64(data,0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -