문제

FieldInfo 객체와 객체가 주어지면 필드의 실제 바이트 표현을 가져와야합니다. 나는 필드가 있다는 것을 알고있다 int,Int32,uint,short 등.

실제 바이트 표현을 어떻게 얻을 수 있습니까? Binaryformatter.serialize는 도움이되지 않습니다. 필요한 것보다 더 많은 정보를 제공하기 때문에 (유형 이름 등을 기록). 그만큼 Marshal 클래스에는 바이트 어레이를 사용할 시설이없는 것 같습니다 (아마도 뭔가 누락 될 수도 있습니다).

감사

도움이 되었습니까?

해결책

실제로 원하는 것이 바이트 배열로 구조를 전송하는 경우 다음과 같은 코드를 시도 할 수도 있습니다.

int rawsize = Marshal.SizeOf(value);
byte[] rawdata = new byte[rawsize];
GCHandle handle = GCHandle.Alloc(rawdata, GCHandleType.Pinned);
Marshal.StructureToPtr(value, handle.AddrOfPinnedObject(), false);
handle.Free();

이것은 주어진 객체를 변환합니다 바이트 배열 RawData에. 나는 이전에 쓴 코드에서 이것을 가져 왔으며 실제로 작동하도록하려면 필요에 맞게 조정해야 할 수도 있습니다. 사용자 정의 구조와 일부 하드웨어와 통신하는 데 사용했지만 내장 유형에도 작동해야합니다 (결국 구조, 그렇지 않습니까?)

구조 구성원을 올바르게 정렬하려면 Structlayout 속성을 사용하여 1 바이트 정렬을 지정하십시오.

[StructLayout(LayoutKind.Sequential, Pack = 1)]

그런 다음 필드에 필요에 따라 Marshalas 속성을 사용합니다. 예를 들어 인라인 배열은 다음과 같습니다.

[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
byte[] _state;

바이트 어레이에서 구조를 다시 얻는 코드는 다음과 같습니다.

public T GetValue<T>()
{
    GCHandle handle = GCHandle.Alloc(RawValue, GCHandleType.Pinned);
    T structure = (T)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), 
                      typeof(T));
    handle.Free();
    return structure;
}

물론이 작업이 작동하기에 원하는 유형을 알아야합니다.

이것은 그 자체로 엔지니어를 처리하지 못할 것입니다. 내 프로젝트에서, 대부분의 필드는 하나의 바이트만이었기 때문에 중요하지는 않았지만, 그 어느 정도의 분야에서는 필드를 비공개로 만들었고 엔디 니스를 처리 할 공개 속성을 추가했습니다.Jon Skeet의 링크 그의 의견에서 그의 대답에 이르기까지 도움이 될 수 있습니다.

이 문제가 필요할 때 원시 값을 저장하는 메시지 클래스를 만들었습니다 (따라서 getValue 메소드, 상단의 코드는 실제로 setValue 메소드의 본문입니다).

다른 팁

bitconverter.getBytes () 사용

바이트를 얻기 위해 비트 컨버터를 사용하는 것보다 먼저 값을 기본 유형으로 변환해야합니다.

byte[] Bytes;

if (valType == typeof(int))
{
    int intVal = (int) GetFieldValue(....);
    Bytes = BitConverter.GetBytes(intVval);
} 
else if (valType == typeof(long))
{
    int lngVal = (long) GetFieldValue(....);
    Bytes = BitConverter.GetBytes(lngVal);
} else ....

당신은 결정적인 임시 표현을 의미합니까? bitconverter.getBytes (반사로 적절하게 선택한 과부하로) 바이트 표현이지만 반드시 그것이 현재 메모리에있는 것은 아닙니다.

아마도 당신이 왜 이것을 원하는지에 대한 자세한 정보를 제공한다면, 우리는 당신을 더 잘 도울 수있을 것입니다.

편집 : 내가 생각할 수있는 현명한 경우에 추가해야합니다. Bitconverter ~ 할 것이다 메모리에서와 동일한 표현을 제공하십시오. 그러나 이상한 결과를 줄 수있는 부동 소수점 표현이 다른 이상한 아키텍처와 관련된 이상한 상황이있을 수 있습니다.

편집 : 다음은 어떻게 진행할 수 있는지 보여주는 완전한 샘플 프로그램입니다.

using System;
using System.Reflection;

public class Test
{
    public int x = 300;

    static void Main()
    {
        Test instance = new Test();
        FieldInfo field = typeof(Test).GetField("x");

        MethodInfo converter = typeof(BitConverter).GetMethod("GetBytes", 
            new Type[] {field.FieldType});

        if (converter == null)
        {
            Console.WriteLine("No BitConverter.GetBytes method found for type "
                + field.FieldType);            
        }
        else
        {
            byte[] bytes = (byte[]) converter.Invoke(null,
                new object[] {field.GetValue(instance) });
            Console.WriteLine("Byte array: {0}", BitConverter.ToString(bytes));
        }        
    }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top