Конвертировать двойные в байты * - PullRequest
0 голосов
/ 14 ноября 2011

Мне нужен код C # для преобразования двойного числа в байт *. Я знаю, что должен использовать исправленный (и небезопасный?), Но не совсем уверен, как ...

Я видел здесь несколько других примеров, но ни один не совсем такой.

Заранее спасибо!

Приветствия

Ответы [ 5 ]

5 голосов
/ 14 ноября 2011

Пока двойная переменная имеет область действия стека (локальная переменная или аргумент метода), вы можете просто использовать приведение указателя.Это работает, потому что переменные области видимости стека не подлежат перемещению сборщиком мусора и, следовательно, не должны быть закреплены.Предотвращает необходимость сначала конвертировать двойное число в byte[].Применяются те же ограничения, что и для ключевого слова fixed, указатель действителен только внутри тела метода:

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

То же самое, что класс BitConverter делает .

5 голосов
/ 14 ноября 2011

Вы можете сделать:

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

или:

public unsafe void YourMethod(double d)
{
    fixed (byte* b = BitConverter.GetBytes(d))
    {
        // Do stuff...
    }
}
3 голосов
/ 14 ноября 2011

Используйте метод 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;
 }
1 голос
/ 14 ноября 2011

Вы можете начать с помощью BitConverter.GetBytes ()

0 голосов
/ 14 ноября 2011

Как утверждают большинство людей, вы можете использовать для этого фиксированный или BitConverter. Но в основном нет. Если вам нужны данные на маршале, .NET сделает это за вас. В большинстве случаев вы не хотите передавать ссылки на управляемую память неуправляемым функциям (поскольку вы не будете иметь никакого контроля над состоянием данных или ссылок) «Исправлено» гарантирует, что данные не будут перемещены или освобождены сборщиком мусора в пределах области действия, и вы получите указатель. Однако за пределами фиксированного блока неуправляемый код все еще может иметь этот указатель, даже если указатель мог быть признан недействительным сборщиком мусора, что быстро приведет к сбою приложения без какой-либо очевидной причины.

В .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.

...