C#指针操作Marshal实例
生活随笔
收集整理的這篇文章主要介紹了
C#指针操作Marshal实例
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
static void Main(string[] args)
{
byte[] a = new byte[]{0,0,0,0};
byte[] b = new byte[] {1,2,3,4};
IntPtr pt = Marshal.AllocHGlobal(a.Length);
//從source數組的startIndex下標開始復制length個對象到ptr;
Marshal.Copy(b,0,pt+0,b.Length);
//從ptr復制length個對象到目標數組的,從目標數組的startIndex開始寫入。
Marshal.Copy((pt+1),a,1,2);
unsafe
{
byte* pb = (byte*) pt;
for (int i = 0; i < a.Length; i++)
{
Console.WriteLine("/b:"+(*pb++) + "/a:" + a[i]);
}
}
//釋放非托管內存;
Marshal.FreeHGlobal(pt);
byte[] arBt = new byte[]{200,0,20,30,40,50,60,70,80,90,11,12,13,14,0x0f,199};
IntPtr ptr = Marshal.AllocHGlobal(arBt.Length);
//寫入數據;
Marshal.Copy(arBt, 0, ptr, arBt.Length);
short[] arSt = new short[arBt.Length / sizeof(short)];
int[] arInt = new int[arBt.Length / sizeof(int)];
//復制為short數據;
Marshal.Copy(ptr, arSt, 0, arSt.Length);
//調整數據 此時arSt不變 下面的arInt改變;
Marshal.WriteByte(ptr, 1, 9);
Marshal.WriteByte(ptr, 10, (byte)(Marshal.ReadByte(ptr,10)*9));
//復制為int數據;
Marshal.Copy(ptr, arInt, 0, arInt.Length);
for (int i = 0; i < arBt.Length; i++)
{
Console.Write(arBt[i] + "-");
}
Console.WriteLine();
for (int i = 0; i < arBt.Length; i++)
{
Console.Write(Marshal.ReadByte(ptr,i) + "-");
}
Console.WriteLine();
unsafe
{ //獲取指定數組中指定索引處的元素的地址
short* ps = (short*)Marshal.UnsafeAddrOfPinnedArrayElement(arSt, 0);
byte[] tmp0 = BitConverter.GetBytes(*ps);
Console.WriteLine(*ps+ "/" + (ushort)*ps+ ",byte>>>&0=" + tmp0[0] + ",&1=" + tmp0[1]);
//獲取指定數組中指定索引處的元素的地址
int* pi = (int*)Marshal.UnsafeAddrOfPinnedArrayElement(arInt, 0);
byte[] tmp1 = BitConverter.GetBytes(*pi);
Console.WriteLine(*pi + "/" + (uint)*pi + ",byte>>>&0=" + tmp1[0] + ",&1=" + tmp1[1] +",&2="+ tmp1[2] + ",&3=" + tmp1[3]);
Console.WriteLine("-----short 2 byte-----");
for (int i = 0; i < arSt.Length; i++)
{
byte[] tmp = BitConverter.GetBytes(arSt[i]);
Console.WriteLine(arSt[i] + "/" + (ushort)arSt[i] + ",byte>>>&0=" + tmp[0] + ",&1=" + tmp[1]);
}
Console.WriteLine("-----int 2 byte-----");
for (int i = 0; i < arInt.Length; i++)
{
byte[] tmp = BitConverter.GetBytes(arInt[i]);
Console.WriteLine(arInt[i] + "/" + (uint)arInt[i] + ",byte>>>&0=" + tmp[0] + ",&1=" + tmp[1] + ",&2=" + tmp[2] + ",&3=" + tmp[3]);
}
}
Marshal.FreeHGlobal(ptr);
unsafe
{
Test tt = new Test();
tt.t1 = 100;
tt.t2 = true;
tt.t3 = 6666;
tt.t4 = 666666;
tt.t6 = false;
string s = "ABCD大師0X00";
char[] chs = s.ToCharArray();
char* block = stackalloc char[100];
fixed (char* cpt = chs)
{
for (int i = 0; i < chs.Length; i++)
{
tt.t5[i] = *(cpt + i);
block[i] = *(cpt + i);
}
Console.WriteLine(new string(tt.t5));
}
}
}
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public unsafe struct Test
{
public byte t1;
public bool t2;
public ushort t3;
public int t4;
//固定大小的緩沖區
public fixed char t5[100];
public bool t6;
}
//----------------------------------
通過上面的例子,我們可以看出,使用C#指針操作內存,非常方便。使用Marshal我們可以獲得非托管內存的指針IntPtr。該指針我們可以強制轉換為
sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal 或 bool的類型指針。之后我們可以Copy,Read ,Write等操作內存。
同C++一樣我們獲得的指針可以通過指針運算符 *,->,&,++,--進行指定內存的數據和位移操作。也可以通過Marshal,將我們的byte類型數據進行類型轉換操作。
Marshal類提供的轉換函數功能之強大。
可參閱https://msdn.microsoft.com/zh-cn/library/system.runtime.interopservices.marshal_methods%28v=vs.80%29.aspx;
總結
以上是生活随笔為你收集整理的C#指针操作Marshal实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在未启动程序情况 点击视图设计器
- 下一篇: 如何将JSON字符串格式化输出