我有这个不安全的代码,我需要安全,以便它可以执行。我知道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");
}
答案 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");
}