[c] 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();

}

오류 : client.h : 24 : 2 : 오류 : ‘{‘토큰 앞에 ‘ :’, ‘,’, ‘;’, ‘}’또는 ‘ attribute ‘가 있어야합니다.

올바른 방법은 무엇입니까?



답변

직접 수행 할 수는 없지만 함수 포인터를 사용하고 “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);

}

그러나 이것을하는 것은 당신에게 정말로 많은 것을 사지 않는다는 것이 밝혀졌습니다. 따라서 외부 함수를 호출하고 인스턴스를 전달할 수 있기 때문에이 스타일로 구현 된 C API가 많지 않습니다.


답변

다른 사람들이 언급했듯이 구조 내부에 함수 포인터를 직접 포함하는 것은 일반적으로 콜백 함수와 같은 특수 목적을 위해 예약되어 있습니다.

아마도 원하는 것은 가상 메소드 테이블과 비슷합니다.

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의 기능이 아닙니다.

당신의 client.AddClient (); call … 이것은 객체 지향 프로그래밍, 즉 C ++ 인 멤버 함수에 대한 호출입니다.

소스를 .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;
}


답변

구조체에 따라 코드를 그룹화하려고합니다. C 그룹은 파일 단위입니다. 모든 함수와 내부 변수를 헤더 또는 헤더와 ac 소스 파일에서 컴파일 된 개체 “.o”파일에 넣습니다.

객체 지향 언어가 아닌 C 프로그램에 대해 객체 지향을 처음부터 다시 만들 필요는 없습니다.

나는 이것을 전에 본 적이 있습니다. 이상한 일입니다. 코더 중 일부는 변경하려는 객체를 변경하는 함수로 전달하는 것을 싫어합니다.

클래스 개체가 항상 멤버 함수의 첫 번째 매개 변수라는 사실을 숨겼지만 숨겨져 있기 때문에 C ++를 비난합니다. 따라서 객체가 함수에 전달 되어도 함수에 전달되지 않는 것처럼 보입니다.

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

C는 유연하며 참조로 전달 될 수 있습니다.

AC 함수는 종종 상태 바이트 또는 정수만 반환하며 종종 무시됩니다. 귀하의 경우 적절한 양식은

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

addClient는 Client.h 또는 Client.c에 있습니다.


답변