Как переслать структуру typedef в .h - PullRequest
22 голосов
/ 31 августа 2011

у меня есть Preprocessor.h

#define MAX_FILES 15

struct Preprocessor {
    FILE fileVector[MAX_FILES];
    int currentFile;
};

typedef struct Preprocessor Prepro;

void Prepro_init(Prepro* p) {
    (*p).currentFile = 0;
}

Тогда я понял, что должен отделить объявления от определений. Итак, я создал Preprocessor.c:

#define MAX_FILES 15

struct Preprocessor {
    FILE fileVector[MAX_FILES];
    int currentFile;
};

typedef struct Preprocessor Prepro;

И Preprocessor.h теперь:

void Prepro_init(Prepro* p) {
    (*p).currentFile = 0;
}

Это, очевидно, не работает, потому что Pr..h не знает тип Prepro. Я уже попробовал несколько комбинаций, ни одна из них не сработала. Я не могу найти решение.

Ответы [ 6 ]

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

Переместите typedef struct Preprocessor Prepro; в заголовок файла и определения в файле c вместе с определением Prepro_init. Это будет заранее объявить для вас без проблем.

Preprocessor.h

#ifndef _PREPROCESSOR_H_
#define _PREPROCESSOR_H_

#define MAX_FILES 15

typedef struct Preprocessor Prepro;

void Prepro_init(Prepro* p);

#endif

Preprocessor.c

#include "Preprocessor.h"

#include <stdio.h>

struct Preprocessor {
    FILE fileVector[MAX_FILES];
    int currentFile;
};

void Prepro_init(Prepro* p) {
    (*p).currentFile = 0;
}
8 голосов
/ 31 августа 2011

Если вы хотите скрыть определение Preprocessor, вы можете просто поместить это в заголовочный файл:

struct Preprocessor;
typedef struct Preprocessor Prepro;

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

1 голос
/ 31 августа 2011

Вы положили в .c то, что должно быть в .h, и наоборот.Prepro_init должно быть в .c файле, и этот файл должен #include "Preprocessor.h".

0 голосов
/ 15 февраля 2017

Я бы посоветовал вам следовать Linus [1] и не использовать typedef struct.

Если вы контролируете библиотеку:

Включить файл

struct Foo;

int foo_get_n(const struct Foo *bar);

В файле реализации

struct Foo
{int n;};

int foo_get_n(const struct Foo *bar)
{return bar->n;}

Если вы не контролируете библиотеку:

Попросите сопровождающего удалить эти загрязняющие определения типов из включаемых файлов.

Резюме

Не использовать typedef struct.

[1] http://yarchive.net/comp/linux/typedefs.html

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

YAS: еще одно решение.

Preprocessor.h

<some code>
    void Prepro_init(Prepro* p) {
        (*p).currentFile = 0;
    }
<some code>

Preprocessor.c

#define MAX_FILES 15

struct Preprocessor {
    FILE fileVector[MAX_FILES];
    int currentFile;
};
typedef struct Preprocessor Prepro;

#include "Preprocessor.h"      //include after defining your structure.

         <some code> 
        {
              struct Prepro p;
              Prepro_init(p);
     <some code> 
          .... using p.currentFile.....
          .....using other members....
     <some code> 
        }
           <some code> 

Теперь это будет работать.Я думаю, что это ваше требование.Надеюсь, это поможет.

Недостаток: Элементы структуры препроцессора, должны быть предварительно определены.т.е. файл заголовка использует член currentFile.Итак, файл c, который включает в себя Preprocessor.h, должен иметь структуру, тип которой определен как Prepro, и эта структура должна включать член currentFile. (В данном случае).

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

0 голосов
/ 31 августа 2011
Файл

Swap .h и .c. Включить заголовок в .c.

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

...