将一段“不安全”的代码块变为“安全”的代码块

3

我有一些不安全的代码,需要使其变得安全以便能够执行。我知道有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");

    }

为什么你需要让它变得安全? - Reed Copsey
2个回答

3

在MSDN页面fixed的示例中,调用代码需要在调用您的方法之前“修复”或“固定”指针,如下所示:

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);
    }
}

固定语句设置一个指向托管变量的指针,并在语句执行期间“锁定”该变量。如果没有固定语句,对可移动托管变量的指针将没有多少用处,因为垃圾回收可能会不可预测地重新定位变量。C#编译器只允许您在fixed语句中分配指向托管变量的指针。

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");
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接