使一块“不安全”的代码“安全”

时间:2012-06-15 01:54:56

标签: c# pointers unsafe

我有这个不安全的代码,我需要安全,以便它可以执行。我知道fixed块,但我不知道如何实现它:

    private static unsafe void PrintHex(byte* data, uint len)
    {
        uint ctr;
        string sep;

        if (len > 64)
        {
            len = 64;
        }

        for (ctr = 0; ctr < len; ctr++)
        {
            if (((ctr & 7) == 0) && (ctr != 0))
            {
                sep = "\n";
            }
            else
            {
                sep = "";
            }
            Console.Error.WriteLine("{0}{1:X}", sep, data[ctr]);
        }

        Console.Error.WriteLine("\n\n");

    }

2 个答案:

答案 0 :(得分:3)

调用代码负责修复&#39;或者&#39; pin&#39;调用方法之前的指针,如本例中fixed的MSDN页面:

class Point
{ 
    public int x, y; 
}

class FixedTest 
{
    // Unsafe method: takes a pointer to an int.
    unsafe static void SquarePtrParam (int* p) 
    {
        *p *= *p;
    }

    unsafe static void Main() 
    {
        Point pt = new Point();
        pt.x = 5;
        pt.y = 6;

        // Pin pt in place:
        fixed (int* p = &pt.x) 
        {
            SquarePtrParam(p);
        }

        // pt now unpinned
        Console.WriteLine ("{0} {1}", pt.x, pt.y);
    }
}
  

fixed语句设置一个指向托管变量的指针和&#34;引脚&#34;   在执行语句期间的那个变量。没有固定,   从那以后,指向可移动托管变量的指针几乎没用   垃圾收集可以无法预测地重定位变量。 C#   编译器只允许您指定一个托管变量的指针   固定陈述。

答案 1 :(得分:3)

  

我有这个不安全的代码,我需要安全,以便它可以执行。

根据定义,任何使用byte*(或任何其他指针类型)的代码在C#中始终是“不安全”的代码。如果不完全更改API,则无法将其转换为“安全”代码。

话虽这么说,这可以在一个托管字节数组上工作:

private static void PrintHex(byte[] data, uint len)
{
    uint ctr;
    string sep;

    if (len > 64)
    {
        len = 64;
    }

    for (ctr = 0; ctr < len && ctr < data.Length; ctr++)
    {
        if (((ctr & 7) == 0) && (ctr != 0))
        {
            sep = "\n";
        }
        else
        {
            sep = "";
        }
        Console.Error.WriteLine("{0}{1:X}", sep, data[ctr]);
    }

    Console.Error.WriteLine("\n\n");
}

这与“安全”托管数组(byte[])的工作方式相同。

另外 - 如果“len”只是数组长度,你可以完全消除该参数,因为托管数组包含它们的长度,与指针不同:

private static void PrintHex(byte[] data)
{
    for (int ctr = 0; ctr < 64 && ctr < data.Length; ctr++)
    {
        string sep;
        if (((ctr & 7) == 0) && (ctr != 0))
        {
            sep = "\n";
        }
        else
        {
            sep = "";
        }
        Console.Error.WriteLine("{0}{1:X}", sep, data[ctr]);
    }

    Console.Error.WriteLine("\n\n");
}