неопределенное объявление структуры struct C - PullRequest
19 голосов
/ 07 марта 2009

У меня есть заголовочный файл port.h, port.c и мой main.c

Я получаю следующую ошибку: 'ports' использует неопределенную структуру 'port_t'

Я подумал, поскольку я объявил структуру в моем файле .h, и фактическая структура в файле .c была в порядке.

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

В моем port.h у меня есть следующее:

/* port.h */
struct port_t;

port.c:

/* port.c */
#include "port.h"
struct port_t
{
    unsigned int port_id;
    char name;
};

main.c:

/* main.c */
#include <stdio.h>
#include "port.h"

int main(void)
{
struct port_t ports;

return 0;
}

Большое спасибо за любые предложения,

Ответы [ 4 ]

25 голосов
/ 07 марта 2009

К сожалению, компилятору нужно знать размер port_t (в байтах) при компиляции main.c, поэтому вам нужно полное определение типа в заголовочном файле.

15 голосов
/ 07 марта 2009

Если вы хотите скрыть внутренние данные структуры port_t, вы можете использовать методику, например, как стандартная библиотека обрабатывает FILE объекты. Код клиента имеет дело только с FILE* элементами, поэтому им не нужно (на самом деле, тогда вообще не может) знать, что на самом деле находится в структуре FILE. Недостаток этого метода заключается в том, что клиентский код не может просто объявить переменную этого типа - они могут иметь только указатели на него, поэтому объект должен быть создан и уничтожен с использованием некоторого API и all использование объекта должно быть через какой-то API.

Преимущество этого состоит в том, что у вас есть хороший чистый интерфейс для того, как port_t объекты должны использоваться, и позволяет вам сохранять приватные вещи частными (непубличные вещи нуждаются в функциях getter / setter для доступа клиента к ним).

Так же, как обрабатывается ввод / вывод FILE в библиотеке C.

6 голосов
/ 07 марта 2009

Общее решение, которое я использую:

/* port.h */
typedef struct port_t *port_p;

/* port.c */
#include "port.h"
struct port_t
{
    unsigned int port_id;
    char name;
};

Вы используете port_p в интерфейсах функций. Вам также потребуется создать специальные оболочки malloc (и бесплатные) в port.h:

port_p portAlloc(/*perhaps some initialisation args */);
portFree(port_p);
0 голосов
/ 07 марта 2009

Я бы порекомендовал другой способ:

/* port.h */
#ifndef _PORT_H
#define _PORT_H
typedef struct /* Define the struct in the header */
{
    unsigned int port_id;
    char name;
}port_t;
void store_port_t(port_t);/*Prototype*/
#endif

/* port.c */
#include "port.h"
static port_t my_hidden_port; /* Here you can hide whatever you want */
void store_port_t(port_t hide_this)
{
    my_hidden_port = hide_this;
}

/* main.c */
#include <stdio.h>
#include "port.h"
int main(void)
{
    struct port_t ports;
    /* Hide the data with next function*/
    store_port_t(ports);
    return 0;
}

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

...