C-функция внутри структуры


Я пытаюсь создать функцию внутри структуры, пока у меня есть этот код:

typedef struct client_t client_t, *pno;
struct client_t
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        pno next;

        pno AddClient() 

        {
            /* code */
        }

};

int main()
{

    client_t client;

    //code ..

    client.AddClient();

}

:клиент.h: 24: 2: ошибка: ожидается‘:’, ‘,’, ‘;’, ‘}’ или'атрибут ‘ before ’ {'token.

Как правильно это сделать ?

5 57

5 ответов:

это не может быть сделано напрямую, но вы можете эмулировать то же самое, используя указатели функций и явно передавая параметр "this":

typedef struct client_t client_t, *pno;
struct client_t
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        pno next;

        pno (*AddClient)(client_t *);    
};

pno client_t_AddClient(client_t *self) { /* code */ }

int main()
{

    client_t client;
    client.AddClient = client_t_AddClient; // probably really done in some init fn

    //code ..

    client.AddClient(&client);

}

оказывается, что делать это, однако, на самом деле не купить вам очень много. Таким образом, вы не увидите много API-интерфейсов C, реализованных в этом стиле, так как вы можете просто вызвать свою внешнюю функцию и передать экземпляр.

как отмечали другие, встраивание указателей функций непосредственно в вашу структуру обычно зарезервировано для специальных целей, таких как функция обратного вызова.

то, что вы, вероятно, хотите, это что-то вроде таблицы виртуальных методов.

typedef struct client_ops_t client_ops_t;
typedef struct client_t client_t, *pno;

struct client_t {
    /* ... */
    client_ops_t *ops;
};

struct client_ops_t {
    pno (*AddClient)(client_t *);
    pno (*RemoveClient)(client_t *);
};

pno AddClient (client_t *client) { return client->ops->AddClient(client); }
pno RemoveClient (client_t *client) { return client->ops->RemoveClient(client); }

Теперь добавление дополнительных операций не изменяет размер client_t структура. Теперь такая гибкость полезна только в том случае, если вам нужно определить много видов клиентов или хотите разрешить пользователям вашего client_t интерфейс возможность увеличить, как ведут себя операции.

такая структура появляется в реальном коде. Уровень OpenSSL BIO выглядит примерно так же, а также интерфейсы драйверов устройств UNIX имеют такой же уровень.

Это будет работать только в C++. Функции в структурах не являются особенностью C.

то же самое касается вашего клиента.AddClient(); вызов ... это вызов функции-члена, которая является объектно-ориентированным программированием, т. е. C++.

преобразуйте свой источник в a .cpp файл и убедитесь, что вы компилируете соответственно.

Если вам нужно придерживаться C, код ниже (вроде) эквивалентен:

typedef struct client_t client_t, *pno;
struct client_t
{
        pid_t pid;
        char password[TAM_MAX]; // -> 50 chars
        pno next;

};


pno AddClient(pno *pclient) 
{
    /* code */
}


int main()
{

    client_t client;

    //code ..

    AddClient(client);

}

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

#include <stdio.h>

typedef struct hello {
    int (*someFunction)();
} hello;

int foo() {
    return 0;
}

hello Hello() {
    struct hello aHello;
    aHello.someFunction = &foo;
    return aHello;
}

int main()
{
    struct hello aHello = Hello();
    printf("Print hello: %d\n", aHello.someFunction());

    return 0;
} 

вы пытаетесь сгруппировать код в соответствии со структурой. Группы с помощью файла. Вы помещаете все функции и внутренние переменные в заголовок или заголовок и объект ".o файл", составленный из исходного файла c.

не стоит изобретать объектную ориентацию с нуля для программы на C, которая не является объектно-ориентированным языком.

Я видел это раньше. Это очень странная вещь. Кодеры, некоторые из них, имеют отвращение к передаче объекта, который они хотят изменить в функцию, чтобы изменить его, Хотя это стандартный способ сделать это.

Я виню C++, потому что он скрыл тот факт, что объект класса всегда является первым параметром в функции-члене, но он скрыт. Таким образом, похоже, что он не передает объект в функцию, даже если это так.

Client.addClient(Client& c); // addClient first parameter is actually 
                             // "this", a pointer to the Client object.

C гибко и может принять проходить вещи ссылкой.

функция C часто возвращает только байт состояния или int, и это часто игнорируется. В если правильная форма может быть

 err = addClient( container_t  cnt, client_t c);
 if ( err != 0 )
   { fprintf(stderr, "could not add client (%d) \n", err ); 

addClient будет в клиенте.h или клиент.c