web-dev-qa-db-ja.com

未定義のC構造体前方宣言

ヘッダーファイル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;
}

提案をありがとう、

19
ant2009

残念ながら、コンパイラはmain.cのコンパイル時にport_tのサイズ(バイト単位)を知る必要があるため、ヘッダーファイルに完全な型定義が必要です。

25
Matthew

port_t構造体の内部データを非表示にする場合は、標準ライブラリがFILEオブジェクトを処理する方法などの手法を使用できます。クライアントコードはFILE*アイテムのみを処理するため、実際にFILE構造に何が含まれているかについての知識は必要ありません(実際、通常はできません)。このメソッドの欠点は、クライアントコードが変数をそのタイプであると単純に宣言できないことです。つまり、変数へのポインタしか持てないため、何らかのAPIを使用してオブジェクトを作成および破棄する必要があります。すべてオブジェクトの使用は、何らかのAPIを介して行う必要があります。

これの利点は、port_tオブジェクトの使用方法に対するすてきなクリーンなインターフェイスがあり、プライベートなものをプライベートに保つことができることです(プライベートでないものには、クライアントがそれらにアクセスするためのゲッター/セッター関数が必要です)。

CライブラリでのFILEI/Oの処理方法と同じです。

15
Michael Burr

私が使用する一般的なソリューション:

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

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

関数インターフェイスでport_pを使用します。 port.hにも特別なmalloc(および無料)ラッパーを作成する必要があります。

port_p portAlloc(/*perhaps some initialisation args */);
portFree(port_p);
6
Hans van Eck

別の方法をお勧めします:

/* 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;
}

通常、ヘッダーファイルで変数を定義するのは適切ではありません。

0
eaanon01