ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Unsafe(不安全代码)
1.A,示例(Sample) 返回顶部

“不安全代码”示例

本示例演示了如何在 C# 中使用非托管代码(使用指针的代码)。

安全说明

提供此代码示例是为了阐释一个概念,它并不代表最安全的编码实践,因此不应在应用程序或网站中使用此代码示例。对于因将此代码示例用于其他用途而出现的偶然或必然的损害,Microsoft 不承担任何责任。

在 Visual Studio 中生成并运行“不安全代码”示例

  1. 在“解决方案资源管理器”中,右击“FastCopy”项目并单击“设为启动项目”。

  2. 在“调试”菜单上,单击“开始执行(不调试)”。

  3. 在“解决方案资源管理器”中,右击“ReadFile”项目并单击“设为启动项目”。

  4. 在“解决方案资源管理器”中,右击“ReadFile”项目并单击“属性”。

  5. 打开“配置属性”文件夹并单击“调试”。

  6. 在“命令行参数”属性中,输入 ..\..\ReadFile.cs

  7. 单击“确定”。

  8. 在“调试”菜单上,单击“开始执行(不调试)”。

  9. 在“解决方案资源管理器”中,右击“PrintVersion”项目并单击“设为启动项目”。

  10. 在“调试”菜单上,单击“开始执行(不调试)”。

从命令行生成并运行“不安全代码”示例

  1. 使用“更改目录”命令转到“Unsafe”目录。

  2. 键入以下命令:

    cd FastCopy
    csc FastCopy.cs /unsafe
    FastCopy
  3. 键入以下命令:

    cd ..\ReadFile
    csc ReadFile.cs /unsafe
    ReadFile ReadFile.cs
  4. 键入以下命令:

    cd ..\PrintVersion
    csc PrintVersion.cs /unsafe
    PrintVersion
1.B,FastCopy 示例代码1(Sample Code)返回顶部

1.B.1, fastcopy.cs

// 版权所有(C) Microsoft Corporation。保留所有权利。
// 此代码的发布遵从
// Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
//
//版权所有(C) Microsoft Corporation。保留所有权利。 // fastcopy.cs
// 编译时使用:/unsafe
using System; class Test
{
// unsafe 关键字允许在下列
// 方法中使用指针:
static unsafe void Copy(byte[] src, int srcIndex,
byte[] dst, int dstIndex, int count)
{
if (src == null || srcIndex < ||
dst == null || dstIndex < || count < )
{
throw new ArgumentException();
}
int srcLen = src.Length;
int dstLen = dst.Length;
if (srcLen - srcIndex < count ||
dstLen - dstIndex < count)
{
throw new ArgumentException();
} // 以下固定语句固定
// src 对象和 dst 对象在内存中的位置,以使这两个对象
// 不会被垃圾回收移动。
fixed (byte* pSrc = src, pDst = dst)
{
byte* ps = pSrc;
byte* pd = pDst; // 以 4 个字节的块为单位循环计数,一次复制
// 一个整数(4 个字节):
for (int n = ; n < count / ; n++)
{
*((int*)pd) = *((int*)ps);
pd += ;
ps += ;
} // 移动未以 4 个字节的块移动的所有字节,
// 从而完成复制:
for (int n = ; n < count % ; n++)
{
*pd = *ps;
pd++;
ps++;
}
}
} static void Main(string[] args)
{
byte[] a = new byte[];
byte[] b = new byte[];
for (int i = ; i < ; ++i)
a[i] = (byte)i;
Copy(a, , b, , );
Console.WriteLine("The first 10 elements are:");
for (int i = ; i < ; ++i)
Console.Write(b[i] + " ");
Console.WriteLine("\n");
}
}

1.B.2,

1.B.EXE,

The first  elements are:

请按任意键继续. . .

1.B,

1.B,PrintVersion 示例代码2(Sample Code)返回顶部

1.B.1, printversion.cs

// 版权所有(C) Microsoft Corporation。保留所有权利。
// 此代码的发布遵从
// Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
//
//版权所有(C) Microsoft Corporation。保留所有权利。 // printversion.cs
// 编译时使用:/unsafe
using System;
using System.Reflection;
using System.Runtime.InteropServices; // 为此程序集指定一个版本号:
[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); // 自动将第三个参数“out string pValue”从 Ansi
// 封送处理为 Unicode:
[DllImport("version.dll")]
unsafe public static extern bool VerQueryValue (byte[] pBlock,
string pSubBlock, out string pValue, out uint len);
// 此 VerQueryValue 重载被标记为“unsafe”,因为
// 它使用 short*:
[DllImport("version.dll")]
unsafe public static extern bool VerQueryValue (byte[] pBlock,
string pSubBlock, out short *pValue, out uint len);
} public class C
{
// Main 被标记为“unsafe”,因为它使用指针:
unsafe public static int Main ()
{
try
{
int handle = ;
// 确定有多少版本信息:
int size =
Win32Imports.GetFileVersionInfoSize("printversion.exe",
out handle); if (size == ) return -; byte[] buffer = new byte[size]; if (!Win32Imports.GetFileVersionInfo("printversion.exe", handle, size, buffer))
{
Console.WriteLine("Failed to query file version information.");
return ;
} short *subBlock = null;
uint len = ;
// 从版本信息获取区域设置信息:
if (!Win32Imports.VerQueryValue (buffer, @"\VarFileInfo\Translation", out subBlock, out len))
{
Console.WriteLine("Failed to query version information.");
return ;
} string spv = @"\StringFileInfo\" + subBlock[].ToString("X4") + subBlock[].ToString("X4") + @"\ProductVersion"; byte *pVersion = null;
// 获取此程序的 ProductVersion 值:
string versionInfo; if (!Win32Imports.VerQueryValue (buffer, spv, out versionInfo, out len))
{
Console.WriteLine("Failed to query version information.");
return ;
} Console.WriteLine ("ProductVersion == {0}", versionInfo);
}
catch (Exception e)
{
Console.WriteLine ("Caught unexpected exception " + e.Message);
} return ;
}
}

1.B.2,

1.B.EXE,

ProductVersion == 4.3.2.1
请按任意键继续. . .

1.B,

1.B,ReadFile 示例代码3(Sample Code)返回顶部

1.B.1, readfile.cs

// 版权所有(C) Microsoft Corporation。保留所有权利。
// 此代码的发布遵从
// Microsoft 公共许可(MS-PL,http://opensource.org/licenses/ms-pl.html)的条款。
//
//版权所有(C) Microsoft Corporation。保留所有权利。 // readfile.cs
// 编译时使用:/unsafe
// 参数:readfile.txt // 使用该程序读并显示文本文件。
using System;
using System.Runtime.InteropServices;
using System.Text; class FileReader
{
const uint GENERIC_READ = 0x80000000;
const uint OPEN_EXISTING = ;
IntPtr handle; [DllImport("kernel32", SetLastError=true)]
static extern unsafe IntPtr CreateFile(
string FileName, // 文件名
uint DesiredAccess, // 访问模式
uint ShareMode, // 共享模式
uint SecurityAttributes, // 安全特性
uint CreationDisposition, // 如何创建
uint FlagsAndAttributes, // 文件特性
int hTemplateFile // 模板文件的句柄
); [DllImport("kernel32", SetLastError=true)]
static extern unsafe bool ReadFile(
IntPtr hFile, // 文件句柄
void* pBuffer, // 数据缓冲区
int NumberOfBytesToRead, // 要读取的字节数
int* pNumberOfBytesRead, // 已读取的字节数
int Overlapped // 重叠缓冲区
); [DllImport("kernel32", SetLastError=true)]
static extern unsafe bool CloseHandle(
IntPtr hObject // 对象句柄
); public bool Open(string FileName)
{
// 打开现有文件进行读取 handle = CreateFile(
FileName,
GENERIC_READ,
,
,
OPEN_EXISTING,
,
); if (handle != IntPtr.Zero)
return true;
else
return false;
} public unsafe int Read(byte[] buffer, int index, int count)
{
int n = ;
fixed (byte* p = buffer)
{
if (!ReadFile(handle, p + index, count, &n, ))
return ;
}
return n;
} public bool Close()
{
// 关闭文件句柄
return CloseHandle(handle);
}
} class Test
{
public static int Main(string[] args)
{
if (args.Length != )
{
Console.WriteLine("Usage : ReadFile <FileName>");
return ;
} if (! System.IO.File.Exists(args[]))
{
Console.WriteLine("File " + args[] + " not found.");
return ;
} byte[] buffer = new byte[];
FileReader fr = new FileReader(); if (fr.Open(args[]))
{ // 假定正在读取 ASCII 文件
ASCIIEncoding Encoding = new ASCIIEncoding(); int bytesRead;
do
{
bytesRead = fr.Read(buffer, , buffer.Length);
string content = Encoding.GetString(buffer,,bytesRead);
Console.Write("{0}", content);
}
while ( bytesRead > ); fr.Close();
return ;
}
else
{
Console.WriteLine("Failed to open requested file");
return ;
}
}
}

1.B.2,

1.B.EXE,

Usage : ReadFile <FileName>
请按任意键继续. . .

1.B,

1.C,下载地址(Free Download)返回顶部
作者:ylbtech
出处:http://ylbtech.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

ylbtech-LanguageSamples-Unsafe(不安全代码)的更多相关文章

  1. Dynamic Code Evaluation:Unsafe Deserialization 动态代码评估:不安全反序列化

  2. JDK中Unsafe类详解

    Java中Unsafe类详解 在openjdk8下看Unsafe源码 浅析Java中的原子操作 Java并发编程之LockSupport http://hg.openjdk.java.net/jdk7 ...

  3. unsafe关键字

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.L ...

  4. java高并发系列 - 第22天:java中底层工具类Unsafe,高手必须要了解

    这是java高并发系列第22篇文章,文章基于jdk1.8环境. 本文主要内容 基本介绍. 通过反射获取Unsafe实例 Unsafe中的CAS操作 Unsafe中原子操作相关方法介绍 Unsafe中线 ...

  5. 深度解密Go语言之unsafe

    目录 指针类型 什么是 unsafe 为什么有 unsafe unsafe 实现原理 unsafe 如何使用 获取 slice 长度 获取 map 长度 map 源码中的应用 Offsetof 获取成 ...

  6. 机器码-字节码-CLR-JIT-托管代码-非托管代码-unsafe-GC-fixed

    0. 机器码 直接由机器码对应平台的CPU执行的指令集, 因此无法在其他指令集的CPU上运行. 无法跨平台. 由本地代码编译得到. (托管代码通过JIT生成) 1. 字节码 即 bytecode 是一 ...

  7. 1. AtomicInteger 、Unsafe 及 CAS方法的整理

    本文摘自: https://blog.csdn.net/fanrenxiang/article/details/80623884 http://ifeve.com/sun-misc-unsafe/ h ...

  8. Netty源码分析之客户端启动过程

    一.先来看一下客户端示例代码. public class NettyClientTest { public void connect(int port, String host) throws Exc ...

  9. 异步编程系列第05章 Await究竟做了什么?

    p { display: block; margin: 3px 0 0 0; } --> 写在前面 在学异步,有位园友推荐了<async in C#5.0>,没找到中文版,恰巧也想提 ...

  10. lesson8:AtomicInteger源码解析及性能分析

    AtomicInteger等对象出现的目的主要是为了解决在多线程环境下变量计数的问题,例如常用的i++,i--操作,它们不是线程安全的,AtomicInteger引入后,就不必在进行i++和i--操作 ...

随机推荐

  1. (转)A Beginner's Guide To Understanding Convolutional Neural Networks

    Adit Deshpande CS Undergrad at UCLA ('19) Blog About A Beginner's Guide To Understanding Convolution ...

  2. 让边框和文本一样高,不受line-height影响,可以使用padding,padding可以用于行内元素

    如果设置了,display:inline-block;边框大小至少和行高一样.这样就可能比文字高.

  3. Linux 数据流重定向

    1.三种数据流重定向1)标准输入(stdin):代码为0,使用0<或0<<,其中代码0可以省略2)标准输出(stdout):代码为1,使用1>或1>>,其中代码1可 ...

  4. C++静态存储,动态存储

    什么是静态存储,动态存储静态存储变量通常是在变量定义时就分定存储单元并一直保持不变, 直至整个程序结束. 动态存储变量是在程序执行过程中,使用它时才分配存储单元, 使用完毕立即释放.典型的例子是函数的 ...

  5. 如何使用投影看着备注分享自己的PPT

    1.  设置多屏幕 一般你的笔记本就是1,   投影是2 2. 设置幻灯片的放映方式 设置幻灯片显示于另外一个监视器  并勾选显示演示者视图 3.  点击放映 就会出现 左上角是ppt本身, 右上角是 ...

  6. EDIUS设置自定义输出的方法

    在做后期视频剪辑时,往往根据需求,需要输出不同分辨率格式的视频文件,那在EDIUS中,如何自定义输出设置,使之符合自己的需要呢?下面小编就来详细讲讲EDIUS自定义输出的一二事吧. 当剪辑完影片,设置 ...

  7. 虚拟化之vmware-截图解释

    故障检测和主机网络隔离 代理会相互通信,并监控群集内各台主机的活跃度.默认情况下,此操作通过每秒交换一次检测信号来完成.如 果15 秒过去后仍未收到检测信号,而且 ping 不到该主机,则系统会声明该 ...

  8. AMD规范:define和require的区别

    define和require在依赖处理和回调执行上都是一样的,不一样的地方是define的回调函数需要有return语句返回模块对象(注意是对象),这样define定义的模块才能被其他模块引用:req ...

  9. IIS不定期Crash和Oracle“未处理的内部错误(-2)”的问题分析

    问题描述:系统不定期报出Oracle“未处理的内部错误(-2)”,严重时IIS会Crash 典型异常日志如下: Exception type:   System.AccessViolationExce ...

  10. js net 除法取整

    1.js中 在编程运算中,除法取整数是比较常用的!一般的编程语言都有内置的函数,JS 脚本也不例外.在JavaScript 中,实现除法取整数有两种方法,即是两个内置函数:Math.floor 和Ma ...