我需要一些C#代码来将double转换为字节*。我知道我必须使用固定(和不安全?),但不确定如何......
我在这里看到了一些其他的例子,但没有一个完全相同。
提前致谢!
干杯
答案 0 :(得分:5)
你可以这样做:
unsafe
{
fixed (byte* b = BitConverter.GetBytes(1.2d))
{
// Do stuff...
}
}
或:
public unsafe void YourMethod(double d)
{
fixed (byte* b = BitConverter.GetBytes(d))
{
// Do stuff...
}
}
答案 1 :(得分:5)
只要double变量具有堆栈范围(局部变量或方法参数),您就可以简单地使用指针强制转换。这是有效的,因为堆栈范围变量不受垃圾收集器的影响,因此不必固定。避免必须首先将双精度转换为byte[]
。与fixed
关键字相同的限制适用,指针仅在方法体内有效:
unsafe void Foo(double d) {
byte* ptr = (byte*)&d;
// Use ptr
//...
}
与BitConverter class does完全相同。
答案 2 :(得分:3)
使用BitConverter.GetBytes方法:http://msdn.microsoft.com/en-us/library/a5be4sc9.aspx
double d = 2.0;
byte[] array = BitConverter.GetBytes(d);
编辑:如果你需要一个C风格的字节*使用:
double d = 2;
byte[] array = BitConverter.GetBytes(d);
IntPtr ptr = Marshal.AllocHGlobal(sizeof(byte) * array.Length);
Marshal.Copy(array, 0, ptr, array.Length);
unsafe
{
byte* pointer = (byte*)ptr;
}
答案 3 :(得分:1)
您可以先使用BitConverter.GetBytes()
开始答案 4 :(得分:0)
正如大多数人所说,你可以使用fixed或BitConverter来做到这一点。但大多数情况下,不要。如果您需要编组数据,.NET将为您执行此操作。在大多数情况下,您不希望将对托管内存的引用传递给非托管函数(因为您无法控制数据的状态或引用) 'Fixed'将确保在范围内,垃圾收集器不会移动或释放数据,您将获得指针。但是,在固定块之外,非托管代码可能仍然具有该指针,即使指针可能已被垃圾回收器无效,这将立即使您的应用程序失败而没有任何明显原因。
在.NET中,使用不安全的代码很少能获得任何有利的性能提升,并且将对托管数据的引用传递给非托管代码并不总是有利的。
但有几个答案:
byte value = 255;
unsafe
{
byte* ptr = &value; // Assign the address of value to ptr
SomeUnsafeCode(ptr);
}
您不需要使用固定的堆栈分配变量,因为它们不是垃圾回收。
对于垃圾收集变量,您需要修复:
byte[] array = SomeGenerator();
unsafe
{
fixed(byte* ptr = array)
{
SomeUnsafeCode(ptr);
}
}
这会将数组固定到内存中,这样垃圾收集器在修复时不会触及数组。
有时您会希望将数据固定在几个代码块上。在这种情况下,您需要使用System.Runtime.InteropServices.GCHandle
。