raydenl
raydenl

Reputation: 439

Convert Double to Byte*

I need some C# code to convert a double to a byte*. I know I have to use fixed (and unsafe?), but not exactly sure how...

Upvotes: 0

Views: 7807

Answers (5)

Hans Passant
Hans Passant

Reputation: 941218

As long as the double variable has stack scope (local variable or method argument), you can simply use a pointer cast. This works because stack scope variables are not subject to moving by the garbage collector and thus don't have to be pinned. Avoids having to convert the double to byte[] first. The same restrictions apply as with the fixed keyword, the pointer is only valid inside the method body:

    unsafe void Foo(double d) {
        byte* ptr = (byte*)&d;
        // Use ptr
        //...
    }

Exact same thing that the BitConverter class does.

Upvotes: 6

GeirGrusom
GeirGrusom

Reputation: 1019

As most people here have stated, you can use fixed, or BitConverter to do this. But mostly, don't. If you need data marshalled, .NET will do this for you. In most cases you do not want to pass references to managed memory to unmanaged functions (as you will have no control over the state of the data, or the references) 'Fixed' will make sure that within the scope, the data will not be moved or released by the garbage collector, and you will get your pointer. However, outside of the fixed block, unmanaged code might still have that pointer, even though the pointer may have been invalidated by the garbage collector, which will promptly make your application fail without any obvious cause.

In .NET, you seldom get any favorable performance increase by using unsafe code, and passing out references to managed data to unmanaged code is not always favorable.

But there are several answers:

byte value = 255;
unsafe
{
  byte* ptr = &value; // Assign the address of value to ptr
  SomeUnsafeCode(ptr);
}

You don't need to use fixed on stack allocated variables, as they are not garbage collected.

For garbage collected variables, you will need fixed:

byte[] array = SomeGenerator();
unsafe
{
  fixed(byte* ptr = array)
  {
    SomeUnsafeCode(ptr);
  }
}

This will pin the array to memory, so that the grabage collector will not touch the array while it is fixed.

Sometimes you would want to pin data over several blocks of code. In this case you would want to use System.Runtime.InteropServices.GCHandle.

Upvotes: 0

Tudor
Tudor

Reputation: 62439

Use BitConverter.GetBytes method: http://msdn.microsoft.com/en-us/library/a5be4sc9.aspx

 double d = 2.0;
 byte[] array = BitConverter.GetBytes(d);

Edit: if you need a C-style byte* use:

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

Upvotes: 3

Arnaud F.
Arnaud F.

Reputation: 8452

You can do:

unsafe
{
    fixed (byte* b = BitConverter.GetBytes(1.2d))
    {
        // Do stuff...
    }
}

or :

public unsafe void YourMethod(double d)
{
    fixed (byte* b = BitConverter.GetBytes(d))
    {
        // Do stuff...
    }
}

Upvotes: 5

Felice Pollano
Felice Pollano

Reputation: 33242

You can start by using BitConverter.GetBytes()

Upvotes: 1

Related Questions