developer tip

C-구조체 내부의 함수

copycodes 2020. 11. 4. 08:07
반응형

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 파일로 변환하고 그에 따라 컴파일하고 있는지 확인하십시오.

If you need to stick to C, the code below is (sort of) the equivalent:

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);

}

How about this?

#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;
} 

You are trying to group code according to struct. C grouping is by file. You put all the functions and internal variables in a header or a header and a object ".o" file compiled from a c source file.

It is not necessary to reinvent object-orientation from scratch for a C program, which is not an object oriented language.

I have seen this before. It is a strange thing. Coders, some of them, have an aversion to passing an object they want to change into a function to change it, even though that is the standard way to do so.

I blame C++, because it hid the fact that the class object is always the first parameter in a member function, but it is hidden. So it looks like it is not passing the object into the function, even though it is.

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

C is flexible and can take passing things by reference.

A C function often returns only a status byte or int and that is often ignored. In your case a proper form might be

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

addClient would be in Client.h or Client.c

참고URL : https://stackoverflow.com/questions/17052443/c-function-inside-struct

반응형