C struct / union с явным (ручным) расположением поля? - PullRequest
0 голосов
/ 25 августа 2011

Что такое эквивалент C этого кода C #?

[StructLayout(LayoutKind.Explicit)]
struct Test
{
    [FieldOffset(0)] int a;  // Integer at byte offset 0
    [FieldOffset(1)] int b;  // Integer at byte offset 1
    [FieldOffset(3)] int c;  // Integer at byte offset 3
};

(Мне все равно, если он не переносимый, например, int предполагается равным 4 байта и т. Д.)

Ответы [ 5 ]

2 голосов
/ 25 августа 2011

В Visual Studio это нормально работает:

#pragma pack(push)

#pragma pack(1)
typedef union
{
    int a;
    struct
    {
        char unused0;
        int b;
    };
    struct
    {
        char unused1;
        char unused2;
        char unused3;
        int c;
    };
} Test;

#pragma pack(pop)
0 голосов
/ 25 августа 2011

Альтернативой использованию объединения является вместо этого использование методов для доступа к значениям, как вы, вероятно, должны делать в любом случае. Хотя это C ++, где вы просили C - но я предполагаю, что C ++ хорош, если вы используете VC ++.

#ifdef __cplusplus
struct Test {
    int a() {
        return *(int*)&values_[0];
    }
    void a(int value) {
        *(int*)&values_[1] = value;
    }
    int b() {
        return *(int*)&values_[1];
    }
    void b(int value) {
        *(int*)&values_[1] = value;
    }
    int c() {
        return *(int*)&values_[3];
    }
    void c(int value) {
        *(int*)&values_[3] = value;
    }

private:
    char[8] values_;
};
#endif
0 голосов
/ 25 августа 2011

Не совсем то, что вы просили, но вы сможете добиться аналогичного эффекта, используя битовые поля .

Кроме того, для Visual C ++, возможно, стоит посмотреть: __declspec(align(#)) или #pragma pack.

0 голосов
/ 25 августа 2011

Вы можете сделать это с помощью объединения, возможно, с некоторыми #defines для упрощения использования.

union Test {
    struct {
        int V_a;
    } s_a;
    struct {
        char V_a;
        int V_b;
    } S_b;
    struct {
        char V_a;
        short V_b;
        int V_c;
    } S_c;

#define a S_a.V_a
#define b S_b.V_b
#define c S_c.V_c
};
0 голосов
/ 25 августа 2011

Как насчет этого?

union u_t {
    struct {
        int V;
    } a;
    struct {
        byte dummy;
        int V;
    } b;
    struct {
        byte dummy1;
        byte dummy2;
        byte dummy3;
        int V;
    } c;
};

Пустые поля используются для принудительного смещения. Я думаю, что некоторые компиляторы могут принудительно выравнивать поля или структуры, поэтому вам нужно убедиться, что при компиляции эта опция отключена. См. Директиву pragma pack . Чтобы получить значения a, b, c, нужно обратиться к полю V в каждой соответствующей структуре в объединении. Например, если u имеет тип u_t, то

  u.c.V = 17;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...