C ++:无法在按位函数后将int类型设置为非标量

问题描述 投票:-1回答:1

我有两个位域:(1)一个用于处理帧(标题),(2)另一个用于处理帧内的子帧(identityFieldO2M)。

union header
{
    unsigned char arr[16]; // 128 bytes allocated

    BitFieldMember<0, 1> SOF;
    BitFieldMember<1, 11> BID;
    BitFieldMember<12, 1> SRR;
    BitFieldMember<13, 1> IDE;
    BitFieldMember<14, 18> IDEX;
    BitFieldMember<32, 1> RTR;
    BitFieldMember<33, 1> r1;
    BitFieldMember<34, 1> r0;
    BitFieldMember<35, 4> DLC;
    BitFieldMember<39, 8> DataField1;
    BitFieldMember<47, 15> CRC;
    BitFieldMember<62, 1> CRCDelim;
    BitFieldMember<63, 1> ACKSlot;
    BitFieldMember<64, 1> ACKdelim;
    BitFieldMember<65, 7> eof;
};

union identityFieldO2M
{
    unsigned char arr[5]; // 3 bytes allocated though only need 29 bits

    BitFieldMember<0, 2> RCI;
    BitFieldMember<2, 14> DOC;
    BitFieldMember<16, 1> PVT;
    BitFieldMember<17, 1> LCL;
    BitFieldMember<18, 1> FSB;
    BitFieldMember<19, 7> SourceFID;
    BitFieldMember<26, 3> LCC;
};

我需要首先处理第一个位域,然后从那里我将这个位域的两个成员组合起来,然后将它们的组合输出运行到另一个位域以确定子帧。然而,我遇到的问题是,当我使用按位函数组合两个位域时,我无法将此数据传回位域。

我想我正在做一些“呃”错的事,但我无法弄清楚这一点。以下是我的实施:

    int main()
    {
    header a;
    memset(a.arr, 0, sizeof(a.arr));
    a = {0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0,0xA0}; // 1010 0000

    cout << hex << a.SOF << endl; // 1 -> 1
    cout << hex << a.BID << endl; // 010 0000 1010 -> 20a
    cout << hex << a.SRR << endl; // 0 -> 0
    cout << hex << a.IDE << endl; // 0 -> 0
    cout << hex << a.IDEX << endl; // 00 1010 0000 1010 0000 -> a0a0
    cout << hex << a.RTR << endl; // 1 -> 1
    cout << hex << a.r1 << endl; // 0 -> 0
    cout << hex << a.r0 << endl; // 1 -> 1
    cout << hex << a.DLC << endl; // 0 000 -> 0
    cout << hex << a.DataField1 << endl; // 0 1010 000 -> 50
    cout << hex << a.CRC << endl; // 0 1010 0000 1010 00 -> 2828
    cout << hex << a.CRCDelim << endl; // 0 -> 0
    cout << hex << a.ACKSlot << endl; // 0 -> 0
    cout << hex << a.ACKdelim << endl; // 1 -> 1
    cout << hex << a.eof << endl; // 010 0000 -> 20

    int BID = a.BID;
    int IDEX = a.IDEX;    
    int result = (BID<<18) | IDEX; // concatenate BID and IDEX together to get 29 bit header

    cout << "test" << endl;
    cout << "BID: " << hex << BID << endl; //-> 20a -> 010 0000 1010
    cout << "IDEX: " << hex << IDEX << endl; //-> a0a0-> 00 1010 0000 1010 0000
    cout << "Identifier Field: " << hex << result << endl; //-> 828a0a0 -> 01 0000 0101 0001 01 0 0 0 0010100 000    
    cout << "Size of Bitfield header: " << sizeof(a) << endl;

    identityFieldO2M b;
    b = result; // **error: no match for 'operator=' (operand types are 'identityFieldO2M' and 'int')**
    memset(b.arr,0,sizeof(b.arr));

    cout << hex << b.RCI << endl; // 01 -> 0x01
    cout << hex << b.DOC << endl; // 0000 0101 0001 01 -> 0x145
    cout << hex << b.PVT << endl; // 0 -> 0x00
    cout << hex << b.LCL << endl; // 0 -> 0x00
    cout << hex << b.FSB << endl; // 0 -> 0x00
    cout << hex << b.SourceFID << endl; // 0010100 -> 0x14
    cout << hex << b.LCC << endl; // 000 -> 0 -> 0x00

    sleep(100);
    return 0;
    }

当我将结合BID和IDEX的结果设置为struct b时,错误发生在哪里:

identityFieldO2M b;
b = result; // **error: no match for 'operator=' (operand types are 'identityFieldO2M' and 'int')**
memset(b.arr,0,sizeof(b.arr));

对于BitFieldMember模板,我在这里使用这个非常有用的模板:https://codereview.stackexchange.com/questions/54342/template-for-endianness-free-code-data-always-packed-as-big-endian

通过BitFieldMember模板的定义,这里是操作数=将值分配到字段中,我怀疑这个问题可能存在?

/* used to assign a value into the field */
inline self_t& operator=(unsigned m)
{
    uchar *arr = selfArray();
    m &= mask;
    unsigned wmask = ~(mask << (7 - (lastBit & 7)));
    m <<= (7 - (lastBit & 7));
    uchar *p = arr + lastBit / 8;
    int i = (lastBit & 7) + 1;
    (*p &= wmask) |= m;
    while (i < bitSize)
    {
        m >>= 8;
        wmask >>= 8;
        (*(--p) &= wmask) |= m;
        i += 8;
    }
    return *this;
}
c++ bit-fields
1个回答
0
投票

根据您的位域定义,您需要使用unsigned char[5]并且它期望大端值(从链接到您获得此代码的位置)。您从编译器错误中看到的不能将它分配给int。一种选择是通过位移将int值复制到大端b.arr中。这样的事情应该做到这一点。

int result = 0x0828a0a0;
identityFieldO2M b;

b.arr[0] = (result >> 24) & 0xFF; // 0x08
b.arr[1] = (result >> 16) & 0xFF; // 0x28
b.arr[2] = (result >> 8) & 0xFF;  // 0xa0
b.arr[3] = result & 0xFF;         // 0xa0
© www.soinside.com 2019 - 2024. All rights reserved.