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

    }
4

2 回答 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# 编译器仅允许您在固定语句中分配指向托管变量的指针。

于 2012-06-15T02:02:20.257 回答
3

我有这个不安全的代码,我需要确保它安全才能执行。

根据定义,任何使用 a 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");
}
于 2012-06-15T02:13:24.640 回答