• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • C# 程序員參考--不安全代碼教程

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    C# 程序員 參考--不 安全 代碼教程: 該教程說明如何在 C# 中使用不安全代碼(使用指針的代碼)。 教程 在 C# 中很少需要使用指針,但仍有一些需要使用的情況。例如,在下列情況中使用允許采用指針的不安全上下文是正確的: 處理磁盤上的現有結構 涉及內部包
    C# 程序員參考--不安全代碼教程:

    該教程說明如何在 C# 中使用不安全代碼(使用指針的代碼)。

    教程

    在 C# 中很少需要使用指針,但仍有一些需要使用的情況。例如,在下列情況中使用允許采用指針的不安全上下文是正確的:

    • 處理磁盤上的現有結構
    • 涉及內部包含指針的結構的高級 COM 或平臺調用方案
    • 性能關鍵代碼

    不鼓勵在其他情況下使用不安全上下文。具體地說,不應該使用不安全上下文嘗試在 C# 中編寫 C 代碼。

    警告   使用不安全上下文編寫的代碼無法被驗證為安全的,因此只有在代碼完全受信任時才會執行該代碼。換句話說,不可以在不受信任的環境中執行不安全代碼。例如,不能從 Internet 上直接運行不安全代碼。

    該教程包括下列示例:

    • 示例 1   使用指針復制一個字節數組。
    • 示例 2   顯示如何調用 Windows ReadFile 函數。
    • 示例 3   顯示如何打印可執行文件的 Win32 版本。

    示例 1

    以下示例使用指針將一個字節數組從 src 復制到 dst。用 /unsafe 選項編譯此示例。

    // fastcopy.cs// compile with: /unsafeusing System; class Test{    // The unsafe keyword allows pointers to be used within    // the following method:    static unsafe void Copy(byte[] src, int srcIndex,        byte[] dst, int dstIndex, int count)    {        if (src == null || srcIndex < 0 ||            dst == null || dstIndex < 0 || count < 0)        {            throw new ArgumentException();        }        int srcLen = src.Length;        int dstLen = dst.Length;        if (srcLen - srcIndex < count ||            dstLen - dstIndex < count)        {            throw new ArgumentException();        }              // The following fixed statement pins the location of            // the src and dst objects in memory so that they will            // not be moved by garbage collection.                      fixed (byte* pSrc = src, pDst = dst)            {                  byte* ps = pSrc;                  byte* pd = pDst;            // Loop over the count in blocks of 4 bytes, copying an            // integer (4 bytes) at a time:            for (int n =0 ; n < count/4 ; n++)            {                *((int*)pd) = *((int*)ps);                pd += 4;                ps += 4;            }             // Complete the copy by moving any bytes that weren't            // moved in blocks of 4:            for (int n =0; n < count%4; n++)            {                *pd = *ps;                pd++;                ps++;            }            }    }      static void Main(string[] args)     {        byte[] a = new byte[100];        byte[] b = new byte[100];        for(int i=0; i<100; ++i)            a[i] = (byte)i;        Copy(a, 0, b, 0, 100);        Console.WriteLine("The first 10 elements are:");        for(int i=0; i<10; ++i)            Console.Write(b[i] + " ");        Console.WriteLine("\n");    }}

    輸出示例

    The first 10 elements are:0 1 2 3 4 5 6 7 8 9

    代碼討論

    • 請注意使用了 unsafe 關鍵字,這允許在 Copy 方法內使用指針。
    • fixed 語句用于聲明指向源和目標數組的指針。它鎖定 srcdst 對象在內存中的位置以便使其不會被垃圾回收移動。當 fixed 塊完成后,這些對象將被解除鎖定。
    • 通過略過數組界限檢查,不安全代碼可提高性能。

    示例 2

    本示例顯示如何從 Platform SDK 調用 Windows ReadFile 函數,這要求使用不安全上下文,因為讀緩沖區需要將指針作為參數。

    // readfile.cs// compile with: /unsafe// arguments: readfile.cs // Use the program to read and display a text file.using System;using System.Runtime.InteropServices;using System.Text; class FileReader{      const uint GENERIC_READ = 0x80000000;      const uint OPEN_EXISTING = 3;      IntPtr handle;       [DllImport("kernel32", SetLastError=true)]      static extern unsafe IntPtr CreateFile(            string FileName,                    // file name            uint DesiredAclearcase/" target="_blank" >ccess,                 // access mode            uint ShareMode,                     // share mode            uint SecurityAttributes,            // Security Attributes            uint CreationDisposition,           // how to create            uint FlagsAndAttributes,            // file attributes            int hTemplateFile                   // handle to template file            );        [DllImport("kernel32", SetLastError=true)]      static extern unsafe bool ReadFile(            IntPtr hFile,                       // handle to file            void* pBuffer,                      // data buffer            int NumberOfBytesToRead,            // number of bytes to read            int* pNumberOfBytesRead,            // number of bytes read            int Overlapped                      // overlapped buffer            );       [DllImport("kernel32", SetLastError=true)]      static extern unsafe bool CloseHandle(            IntPtr hObject   // handle to object            );            public bool Open(string FileName)      {            // open the existing file for reading                      handle = CreateFile(                  FileName,                  GENERIC_READ,                  0,                   0,                   OPEN_EXISTING,                  0,                  0);                  if (handle != IntPtr.Zero)                  return true;            else                  return false;      }       public unsafe int Read(byte[] buffer, int index, int count)       {            int n = 0;            fixed (byte* p = buffer)             {                  if (!ReadFile(handle, p + index, count, &n, 0))                        return 0;            }            return n;      }       public bool Close()      {            // close file handle            return CloseHandle(handle);      }} class Test{      public static int Main(string[] args)      {            if (args.Length != 1)            {                  Console.WriteLine("Usage : ReadFile <FileName>");                  return 1;            }                        if (! System.IO.File.Exists(args[0]))            {                  Console.WriteLine("File " + args[0] + " not found.");                   return 1;            }             byte[] buffer = new byte[128];            FileReader fr = new FileReader();                        if (fr.Open(args[0]))            {                                    // Assume that an ASCII file is being read                  ASCIIEncoding Encoding = new ASCIIEncoding();                                    int bytesRead;                  do                   {                        bytesRead = fr.Read(buffer, 0, buffer.Length);                        string content = Encoding.GetString(buffer,0,bytesRead);                        Console.Write("{0}", content);                  }                  while ( bytesRead > 0);                                    fr.Close();                  return 0;            }            else            {                  Console.WriteLine("Failed to open requested file");                  return 1;            }      }}

    輸入示例

    在編譯和運行此示例時,下列來自 readfile.txt 的輸入將產生在“輸出示例”中顯示的輸出。

    line 1line 2

    輸出示例

    line 1line 2

    代碼討論

    傳遞到 Read 函數的字節數組是托管類型。這意味著公共語言運行庫垃圾回收器可能會隨意地對數組使用的內存進行重新定位。fixed 語句允許您獲取指向字節數組使用的內存的指針,并且標記實例,以便垃圾回收器不會移動它。

    fixed 塊的末尾,將標記該實例以便可以移動它。此功能稱為聲明式鎖定。鎖定的好處是系統開銷非常小,除非在 fixed 塊中發生垃圾回收(但此情況不太可能發生)。

    示例 3

    本示例讀取并顯示可執行文件的 Win32 版本號,在本示例中此版本號與程序集版本號相同。本例中使用的可執行文件為 printversion.exe。本示例使用 Platform SDK 函數 VerQueryValue、GetFileVersionInfoSize 和 GetFileVersionInfo 從指定的版本信息資源中檢索指定的版本信息。

    本示例使用了指針,因為它可以簡化在其簽名中使用指向指針的指針(這在 Win32 API 中很常見)的方法的使用。

    // printversion.cs// compile with: /unsafeusing System;using System.Reflection;using System.Runtime.InteropServices; // Give this assembly a version number:[assembly:AssemblyVersion("4.3.2.1")] public class Win32Imports {      [DllImport("version.dll")]      public static extern bool GetFileVersionInfo (string sFileName,            int handle, int size, byte[] infoBuffer);      [DllImport("version.dll")]      public static extern int GetFileVersionInfoSize (string sFileName,            out int handle);         // The third parameter - "out string pValue" - is automatically      // marshaled from ANSI to Unicode:      [DllImport("version.dll")]      unsafe public static extern bool VerQueryValue (byte[] pBlock,            string pSubBlock, out string pValue, out uint len);      // This VerQueryValue overload is marked with 'unsafe' because       // it uses a short*:      [DllImport("version.dll")]      unsafe public static extern bool VerQueryValue (byte[] pBlock,            string pSubBlock, out short *pValue, out uint len);} public class C {      // Main is marked with 'unsafe' because it uses pointers:      unsafe public static int Main ()       {            try             {                  int handle = 0;                  // Figure out how much version info there is:                  int size =                        Win32Imports.GetFileVersionInfoSize("printversion.exe",                        out handle);                   if (size == 0) return -1;                   byte[] buffer = new byte[size];                   if (!Win32Imports.GetFileVersionInfo("printversion.exe", handle, size, buffer))                  {                        Console.WriteLine("Failed to query file version information.");                        return 1;                  }                   short *subBlock = null;                  uint len = 0;                  // Get the locale info from the version info:                  if (!Win32Imports.VerQueryValue (buffer, @"\VarFileInfo\Translation", out subBlock, out len))                  {                        Console.WriteLine("Failed to query version information.");                        return 1;                  }                   string spv = @"\StringFileInfo\" + subBlock[0].ToString("X4") + subBlock[1].ToString("X4") + @"\ProductVersion";                   byte *pVersion = null;                  // Get the ProductVersion value for this program:                  string versionInfo;                  if (!Win32Imports.VerQueryValue (buffer, spv, out versionInfo, out len))                  {                        Console.WriteLine("Failed to query version information.");                        return 1;                  }                  Console.WriteLine ("ProductVersion == {0}", versionInfo);            }            catch (Exception e)             {                  Console.WriteLine ("Caught unexpected exception " + e.Message);            }                  return 0;      }}

    輸出示例

    ProductVersion == 4.3.2.1

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>