C#_Marshal.Copy 方法的使用

(1)Marshal.Copy 方法 (IntPtr, Byte[], Int32, Int32)

從 Unmanaged 記憶體指標將資料複製到 Managed 8 位元
不帶正負號的整數 (Unsigned Integer) 陣列。


public static void Copy(
 IntPtr source,
 byte[] destination,
 int startIndex,
 int length
)


參數:
source
Type: System.IntPtr
要複製的來源記憶體指標。
destination
Type: System.Byte[]
要複製到其中的陣列。
startIndex
Type: System.Int32
複製應該在此處開始之目的地陣列中以零起始的索引。
length
Type: System.Int32
要複製的陣列元素數目。

例外狀況
ExceptionCondition
ArgumentNullException
sourcedestinationstartIndex 或 length 為 null
MSDN參考說明連結
Marshal.Copy 方法 (IntPtr, Byte[], Int32, Int32)
https://msdn.microsoft.com/zh-tw/library/ms146631(v=vs.110).aspx

Marshal.Copy 方法 (Int32[], Int32, IntPtr, Int32)
https://msdn.microsoft.com/zh-tw/library/ms146629(v=vs.110).aspx

示範

記得  引入 System.Runtime.InteropServices  命名空間



第一階段練習code



using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;//for Marshal
using System.Text;
using System.Threading.Tasks;

namespace Mashal_Copy_ex1
{
    //Marshal.Copy 方法 (IntPtr, Byte[], Int32, Int32)使用示範
    class Program
    {
        static void Main(string[] args)
        {
            //創建一個有賦予數值(managed)的byte陣列(數組)
            byte[] managedArray = { 1, 2, 3, 4 };
            //初始化一塊unmanaged memory 來存放unmanaged的byte陣列空間
            int size = Marshal.SizeOf(managedArray.Length);//有四個所以size回傳4個byte
            //宣告一個IntPtr 用來分配大小的記憶體空間
            //Marshal.AllocHGlobal 方法 (記憶體中需要的byte數目)
            IntPtr ptr = Marshal.AllocHGlobal(size);


            //將Array的資料copy到unmanaged 的 memory中
            //Marshal.Copy(要複製的一維陣列,來源陣列中以零起始的索引,目的地記憶體指標,要複製的陣列元素數目);
            Marshal.Copy(managedArray,0,ptr,managedArray.Length);

            Console.WriteLine("The array was copied to unmanaged memory.");
            Console.ReadKey();
        }
    }
}



第二階段

Marshal.Copy 可以將Array 中的資料拷貝給IntPtr 所指向的位址,
反過來,也可以將IntPtr 位址中的內容拷貝給Array。

不管是從哪裡拷貝到哪裡,當中都有一個參數startIndex。

那麼這個startIndex 到底是指IntPtr 的偏移量呢,還是Array 的偏移量呢?

右鍵 --> Add Watch






第二階段程式碼_練習局部範圍的指針記憶體copy


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;//for Marshal
using System.Text;
using System.Threading.Tasks;

namespace Mashal_Copy_ex1
{
    //Marshal.Copy 方法 (IntPtr, Byte[], Int32, Int32)使用示範
    class Program
    {
        static void Main(string[] args)
        {
            //初始化一個managed的整數陣列
            int[] buffer = { 1, 2, 3, 4 };

            //取得大小(所佔byte有幾個)
            int size = Marshal.SizeOf(buffer.Length);

            //配置兩個整數陣列
            int[] buffer1 = new int[3];
            int[] buffer2 = new int[3];

            IntPtr ptr = Marshal.AllocHGlobal(size);
            //將buffer陣列中index:1的元素2複製到ptr指標中
            Marshal.Copy(buffer, 1, ptr, 1);

            /*
             Marshal.Copy(IntPtr source,
                          byte[] destination,
                          int startIndex,
                          int length
                      ); 
             
             Marshal.Copy(要複製的來源記憶體指標
                          要複製到其中的陣列
                          目的地陣列中以零起始的索引
                          要複製的陣列元素數目
                    );
             */

            //將ptr指標中所存的2複製到buffer1這個整數陣列的編號0位置
            Marshal.Copy(ptr, buffer1, 0, 1);

            Marshal.Copy(ptr,buffer2,1,1);


            Console.ReadKey();
        }
    }
}


















留言

這個網誌中的熱門文章

經得起原始碼資安弱點掃描的程式設計習慣培養(五)_Missing HSTS Header

經得起原始碼資安弱點掃描的程式設計習慣培養(三)_7.Cross Site Scripting(XSS)_Stored XSS_Reflected XSS All Clients

(2021年度)駕訓學科筆試準備題庫歸納分析_法規是非題