Инициализация союза - PullRequest
1 голос
/ 24 мая 2011

Предыдущий код:

struct Inet_address{
char v4[4];
};
extern "C" Inet_address Inet_loopback = 
{
  {127,0,0,1}
};

После изменения:

Я сделал Inet_address союзом Здесь инет адрес это объединение

union Inet_address{
char v4[4];
char v6[16];
};

Теперь я хочу сделать ту же операцию на внешнем "C". Скажем,

extern "C" Inet_address Inet_loopback = 
{
 if(some condition)
  {127,0,0,1}  //It should be Inet_address.v4
 else
    { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }  //This should be Inet_address.v6
};

Пожалуйста, предложите правильный способ добиться этого, поскольку я получаю ошибку здесь.

Ответы [ 4 ]

5 голосов
/ 24 мая 2011

Для этого не следует использовать массивы символов - создайте объединение из in_addr и in6_addr:

typedef union {
    struct in_addr inaddr;
    struct in6_addr in6addr;
} in46_addr_t;

Чтобы установить адрес обратной связи ipv4:

addr.inaddr.s_addr = INADDR_LOOPBACK;

Для IPv6:

addr.in6addr = in6addr_loopback; // pre-defined global variable (note: assumes linux socket API)
2 голосов
/ 25 мая 2011

Ответ bdonlan хорош, но если вы хотите что-то полностью POSIXly переносимое, смотрите getaddrinfo () .(Ну, во всяком случае, современный POSIX.)

struct addrinfo hints = { 0 };
hints.ai_family = AF_INET6;
hints.ai_flags = AI_NUMERICHOST;
struct addrinfo *result = NULL;

getaddrinfo("::1", NULL, &hints, &result);

// result[0].ai_addr is now a pointer to the localhost IPv6 address as a sockaddr_in6
// struct.

freeaddrinfo(result);
1 голос
/ 24 мая 2011

Поскольку вы (судя по тегам, прикрепленным к этому вопросу), вы используете c ++ для этого проекта, вам вообще не следует использовать объединение. С. использовал союзы как своего рода примитивный полиморфизм. В С ++ наследование доступно и является гораздо более надежным методом реализации полиморфизма.

Я бы порекомендовал использовать для этого небольшую наследственную наследственность: (Примечание: это скелетный код, который предназначен только для того, чтобы дать вам представление о том, как это может работать)

class Inet_address
{
    vector<int> _address;

    public:
        Inet_address();
        virtual ~Inet_address();

        // pure virtual function...special behavior implemented in sub classes
        virtual vector<int> loopback() = 0;
}

class Inet_address_v4 : public Inet_address
{
    public:
        Inet_address_v4();
        virtual ~Inet_address_v4();

        // special behavior for v4
        virtual vector<int> loopback();
}

class Inet_address_v6 : public Inet_address
{
    public:
        Inet_address_v6();
        virtual ~Inet_address_v6();

        // special behavior for v6
        virtual vector<int> loopback();
}

int main()
{
    // Create a new v4 address object
    Inet_address* my_v4_addr = new Inet_address_v4();

    // Create a new v6 address object
    Inet_address* my_v6_addr = new Inet_address_v6();

    vector<Inet_address*> addresses;

    addresses.push_back( my_v4_addr );
    addresses.push_back( my_v6_addr );

    // The loopback function is called in the same way for both sub-classes
    for( unsigned int i=0; i<addresses.size(); i++ )
    {
        Inet_address* curr_adr = addresses[i];
        curr_addr->loopback();
    }

    return 0;
}

Этот подход обычно является стандартным методом, используемым в c ++. Это действительно мощный подход, потому что он может позволить вам создавать множество различных типов объектов с похожим поведением, которыми можно манипулировать, используя одни и те же вызовы функций.

См. Это для обзора наследования c ++: http://www.cplusplus.com/doc/tutorial/inheritance/

Удачи!

1 голос
/ 24 мая 2011

По моему мнению, такое объединение не имеет смысла, поскольку Inet_address будет занимать в памяти размер самого большого массива. Почему вы не используете только один массив из 16 элементов? Кроме того, вам придется поместить свою инициализацию в функцию, если ваше состояние может быть оценено только во время выполнения. Если ваше состояние может быть оценено во время компиляции, то, что вы пытаетесь сделать, может быть достигнуто с помощью шаблонов и метапрограммирования, но оно не будет простым и трудно читаемым.

Не могли бы вы рассказать нам больше о вашем состоянии?

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