2016-07-01 12 views
1

ソースファイルまたは構造体自体に構造体関数を定義する方法については混乱します。はい私は同様のスタックオーバーフローの質問を読んだが、それは構造体自体で宣言された関数を定義できるかどうか尋ねる。あなたが見ることができるように、私は構造体に初期化されている関数ポインタを定義しようとしているソースファイルまたは構造体自体に構造体関数を定義する方法

typedef struct 
{ 
    char *name; 
    bool initialized; 
    int32_t status; 
    int (*initialize)(void); 
} NetworkDriver; 

:基本的には簡単な問題で、私はこの「NetworkDriver」構造体を持っています。これをどうやってやるの?

+1

あなたはそれを呼び出すときに何をしなければならないのですか?それはどのような 'NetworkDriver 'のインスタンスを使用しているかをどのように知るでしょうか? – paddy

+0

@paddy initalizeは、0または1のいずれかの整数を返します。0は、正常に初期化されていることを意味し、1は、それを意味しません。もし私がブールを初期化していないのであれば、ブールを正直にして、そうでなければ真実にしてください...そして、エラーがあればなぜ初期化しなかったのかというように、初期化のステータス番号を保存してください。 – amanuel2

+0

"構造体で初期化された " - それは意味をなさないと思われる。構造体で初期化された 'name'をどのように定義しますか? – immibis

答えて

3

Cない C++)としてタグ付けされた問題は、所定のコードスニペットはCのstruct functionのようなものが存在しないことに留意すべきである、initializeは単に構造体typedefさのデータメンバーでありますNetworkDriverは、引数をとらずにintを返す関数へのポインタと宣言されています。

変数の定義と使用の仕組みは、関数ポインタと同じです。与えられたプロトタイプの関数を指すように設定する必要があります。通常の関数構文で呼び出すことができます。

#include <stdio.h> 

typedef struct 
{ 
    int (*initialize)(void); 
} NetworkDriver; 

int init(void) 
{ 
    printf("initializing...\n"); 
    return 0; 
} 

int main(void) 
{ 
    NetworkDriver nd; 
    nd.initialize = init; 

    nd.initialize(); // prints 'initializing...' 

    return 0; 
} 
+0

しかし、私はNetworkDriverのインスタンスごとに初期化関数を必要としています.....イーサネット、無線などの複数のネットワークドライバがあります。 – amanuel2

+2

'C'では、明示的に構造体の各インスタンスを初期化する必要がありますあなたが作成します。 'C++ 'ではコンストラクタやメンバ関数を使うことができますが、あなたの質問には' C'というタグが付いています。 – dxiv

+0

私はC. umでこれを作成していますので、おそらくそれを動的に行うことはできませんか? – amanuel2

0

問題が発生するかどうかわかりません。あなたのコードフラグメントで何をしたのかと宣言するでした。このタイプのインスタンスはありませんが、初期化することはできません。インスタンスを宣言する必要があります。末尾の行に追加するか、}NetworkDriver var;を追加するか、後で別の行を追加してください:NetworkDriver var;

いずれにせよ、={"whatever",true,0,&function}を追加することでこのインスタンスを初期化できます。またはその関数ポインタだけを追加して、var.initialize = &funciton;という行を追加します。

+0

提案したように、 'NetworkDriver'の後に' var'を追加することはできません。 –

0

以下は、あなたが話しているものに最も近いものです。私はいくつかの変更を行いました(boolの代わりにintを使用しました)、NetworkDriver構造体にもう1つの関数ポインタを追加し、関数にパラメータを追加しました。

しかし、NetworkDriverの各インスタンスには独自のinitialize機能が必要です。しかし、私がしたことは、initialize関数を一度定義し、NetworkDriverの各インスタンスにそれへのポインタがあることです。あなたが言っているものとまったく同じではありませんが、これは私が考えることができるものです。

dxibが答えたところでは、関数を明示的に呼び出す必要があります。私はC++のコンストラクタのようなものではありません。また、呼び出す前に、構造内のこれらの関数ポインタに関数のアドレスを明示的に割り当てる必要があります。

#include<stdio.h> 
#include<stdlib.h> 

#define TRUE 1 
#define FALSE 0 

#define NO_ERR   10 
#define NAME_ERR  11 
#define INITIALIZED_ERR 12 

typedef struct 
{ 
    char *name; 
    int initialized; 
    int32_t status; 
    int (*initialize)(void *, char *); 
    void (*disp_info)(void *); /* Note: one more func pointer */ 
}NetworkDriver; 


/* Function prototype declarations */ 
int nd_init(void *ndr, char *name); 
void nd_disp_info(void *ndr); 

/* main: test NetworkDriver and nd_init */ 
int main(void) 
{ 
    NetworkDriver nd; 

    nd.initialized = FALSE; 
    nd.initialize = nd_init; 
    nd.disp_info = nd_disp_info; 

    if (nd.initialize(&nd, "foo")) { /* Initialize driver */ 
      printf("Error: Initialization error\n"); 
      exit(1); 
    } 

    nd.disp_info(&nd); /* display nd's info */ 

/* nd_init: initialize a NetworkDriver */ 
int nd_init(void *ndr, char *name) 
{ 
    NetworkDriver *nd; 

    nd = (NetworkDriver *) ndr; 

    if (!(nd->name = name)) { 
      nd->status = NAME_ERR; 
      return 1; 
    } 


    if (nd->initialized != TRUE) { 
      if (!(nd->initialized = TRUE)) { 
        nd->status = INITIALIZED_ERR; 
        return 1; 
      } 
    } 


    /* Successfully initialized */ 
    nd->status = NO_ERR; 
    return 0; 
} 

/* nd_disp_info: display NetworkDriver info */ 
void nd_disp_info(void *ndr) 
{ 
    NetworkDriver *nd; 

    nd = (NetworkDriver *) ndr; 

    /* If this driver was not initialized without err */ 
    if (nd->status != NO_ERR) { 
      printf("NetworkDriver was not initialized correctly\n"); 
      return; 
    } 

    /* Print info */ 
    printf("=== NetworkDriver info ===\n"); 
    printf("Name: %s\n", nd->name); 
    printf("Initialized ? %s\n", nd->initialized == TRUE ? "TRUE" : 
          "FALSE"); 
    printf("Status: %d\n", (int) nd->status); 
}