Int, чтобы плавать указатели - PullRequest
3 голосов
/ 16 февраля 2012

В C ++ есть значение с плавающей точкой, помещаемое в int:

int value = *(int *)(&myFloatValue);

Это значение передается программе, которую я пишу на C #. Во время выполнения неизвестно, будет ли значение иметь тип int или float. Я должен учитывать оба варианта. Очевидно, что если это int, у меня уже есть. Однако, если это float, мне нужно изменить его (не приведение) к его значению float. Как мне это сделать? Я пытался использовать указатели в C #, но это было безуспешно.

Ответы [ 5 ]

8 голосов
/ 16 февраля 2012

BitConverter.GetBytes и BitConverter.ToFloat().

4 голосов
/ 16 февраля 2012

Если я понимаю, что вы спрашиваете, я рекомендую профсоюзы?

[StructLayout(LayoutKind.Explicit)]
struct IntOrFloat
{
    [FieldOffset(0)]
    public int asInt32;
    [FieldOffset(0)]
    public float asFloat;
}

Я думаю, что это сработает.

2 голосов
/ 16 февраля 2012

Один из вариантов - использовать BitConverter:

// assuming 'bytes' is byte[4]
float value = BitConverter.ToSingle(bytes);
//   or     = BitConverter.ToSingle(BitConverter.GetBytes(integer));

Еще одна вещь, которую вы могли бы сделать, если бы знали, какого типа будет значение, прежде чем вызывать этот метод, это использовать перегрузку операторов на стороне P / Invoke:

// [DllImport("x.dll")]
// public static extern void YourCall(ref float value);

// [DllImport("x.dll")]
// public static extern void YourCall(ref int value);

if (someCondition)
{
    float value = 0.0f;
    NativeMethods.YourCall(ref value);
    this.frob(value);
}
else
{
    int value = 0;
    NativeMethods.YourCall(ref value);
    this.frob(value);
}
1 голос
/ 17 февраля 2012

Вы можете использовать BitConverter, но это действительно некрасиво.Ваш интерфейс C ++ to C # действительно беспорядочный - передача значения, которое может быть либо int, либо float в одном аргументе.Я предлагаю вам сделать одно из двух:

  1. Pass и int и float, и решить, какой из них правильный в C #
  2. Пропустить только одинчисло, в типе, который может содержать все числа с плавающей точкой и все целые числа - double.
1 голос
/ 16 февраля 2012

Сделайте обратное в коде C #:

float myFloatValue = *(float *)(&value);

И это должно сработать.

(Просто убедитесь, что значение не внутри управляемого типа, оно должно быть само по себе)

РЕДАКТИРОВАТЬ: Убедитесь, что вы объявляете тело кода, в котором вы делаете это как unsafe

...