C#으로 int/short/byte 구조 바이트 표현을 얻습니다.
-
03-07-2019 - |
문제
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));
}
}
}