C++에서의 Bit Structure 구현

안녕하세요. C# WPF를 개발하는 중 막히는 부분이 있어 글을 쓰게 되었습니다.
다름이 아니라 C, C++의 경우 Struct Bit 필드가 존재하여 Bit 구조체를 적절히 선언하여 입력 받은 데이터( Packet )를 Parsing하여 데이터를 처리하는 경우가 많았습니다.
C# WPF로 관련 내용을 구현하려 하니 C#에서 bit structure 지원이 되지 않아 보통 실무에서는 어떤 식으로 Bit단위 데이터를 처리하는지 궁금해 졌습니다.
짧은 기간 C# 경험으로 찾을 수 없는 부분이라 ㅠㅠ
혹시 알고 계신 부분이 있으시거나, 저와 같은 고민과 해결 방법을 찾으신 분이 있으시면 공유 해주시면 감사하겠습니다!!
뿐만아니라 Socket 통신을 통해 받은 Packet Data를 적절히 Parsing하고 처리할 수 있는 팁을 알고 계신분이 있으시면 공유 부탁드리겠습니다.

현재 저는 시프트 연산 처리를 통해 받은 데이터 bit 처리를 하고 있습니다. ㅠㅠ

2개의 좋아요

C#에서는 비트 필드를 지원하지 않아요.

BitArray 또는 BitVector32를 이용해 비트 값을 취해 처리해야 합니다.

5개의 좋아요

참고 하시도록 BitVector32 예제를 만들어보았습니다.

// 비트 필드를 취해야 하는 데이터가 '2비트 모드', '4비트 명렁어', '10비트 데이터'라고 가정
using System.Collections.Specialized;

ushort raw = 0b01_0010_1000000001;

var dataSection = BitVector32.CreateSection(0b1111111111);
var commandSection = BitVector32.CreateSection(0b1111 , dataSection);
var modeSection = BitVector32.CreateSection(0b11, commandSection);

var data = new BitVector32(raw);

Console.WriteLine(data);
Console.WriteLine($"Mode = {data[modeSection]}");
Console.WriteLine($"Command = {data[commandSection]}");
Console.WriteLine($"Data = {data[dataSection]}");
2개의 좋아요

그런데 어짜피 BitVector32의 섹션 구현은,

(int)((_data & (uint)(section.Mask << section.Offset)) >> section.Offset);

이어서요, 그냥 비트 연산을 하는 정적 도움 클래스를 만드시고 사용하셔도 무방할 것 같습니다.

3개의 좋아요

일반적으로 BinaryReader를 이용할 수 있습니다.

3개의 좋아요

좋은 정보 감사합니다!

3개의 좋아요

비트 필드 값을 구하는 것을 아래처럼 확장 메서드로 만들어 사용할 수 도 있겠습니다.

// 비트 필드를 취해야 하는 데이터가 '2비트 모드', '4비트 명렁어', '10비트 데이터'라고 가정
using System.Collections.Specialized;
using System.Runtime.CompilerServices;

ushort raw = 0b01_0010_1000000001;

var dataSection = BitVector32.CreateSection(0b1111111111);
var commandSection = BitVector32.CreateSection(0b1111 , dataSection);
var modeSection = BitVector32.CreateSection(0b11, commandSection);

var data = new BitVector32(raw);

Console.WriteLine(data);
Console.WriteLine($"Mode = {data[modeSection]}");
Console.WriteLine($"Command = {data[commandSection]}");
Console.WriteLine($"Data = {data[dataSection]}");

Console.WriteLine("---");

Console.WriteLine($"Mode = {raw.GetBitField(14, 2)}");
Console.WriteLine($"Command = {raw.GetBitField(10, 4)}");
Console.WriteLine($"Data = {raw.GetBitField(0, 10)}");


static class BitFieldExtension
{
    public static void SetBitField(this ushort @this, int bitOffset, int bits)
    {
        // ...
    }

    public static int GetBitField(this ushort @this, int bitOffset, int bits)
    {
        var mask = (1 << (bitOffset + bits)) - 1;
        return (@this & mask) >> bitOffset;
    }
}
3개의 좋아요

미흡 하지만 공용으로 Json형식으로 packet정보를 입력 받아, byte or bit feild단위로 packet을 읽을 수 있는 개인 project를 만들어 봤습니다. 공유 드립니다.

5개의 좋아요

죄송한데요…
@dimohy 님 댓글 보다가 또 가면 증후군 걸렸습니다… :face_exhaling:

2개의 좋아요

네? 어떤것 때문에요??

3개의 좋아요

농담입니다.
진짜 얼마나 노력하셨으면 그 경지에 가셨을지 감히 짐작도 안돼서요…
댓글 하나하나에 (어마어마한) 내공이 느껴집니다 :+1:

2개의 좋아요

아… 저도 아는 것만 알고 모르는 것은 모릅니다. ^^;;;

3개의 좋아요

여러모로 좋은 의미에서 농담한건데 혹시 기분 나쁘셨다면 죄송합니다…
이 커뮤니티를 통해서 항상 좋은 자극 받고있습니다.
감사해용

2개의 좋아요

기분 나쁠 이유가 있나요; 왜 그렇게 생각하시는지 궁금해서 여쭤본 것 뿐입니다.

2개의 좋아요