2016-07-20 14 views
0

上記の警告が表示されて理解していますが、修正方法はわかりません。私のコードは以下の通りですが、基本的には、構造体に関数ポインタを格納し、メインから呼び出す別の関数で構造体を初期化しています。コードは、デフォルトの関数(つまりfree())で使用するとコンパイルされるようですが、以下のtest_func関数で使用するとコンパイルできません。思考?関数ポインタが互換性がないポインタ型void(my_type *)からvoid(*)(void *)

構造体:

typedef struct my_struct { 
    my_type **double_pointed; 
    int num; 
    void (*funcp)(void *data); 
    } my_struct_t; 

初期化機能:私はを指すようにしたい

my_struct_t *init(int num, void (*my_funcp)(void *data)) { 

    // unimportant code to the problem, but basically just some mallocs for the other data 

    my_struct_t *my_str; 
    my_str->funcp = my_funcp; 

    return struct; 
} 

機能:

void desired_func(my_type *obj) {} 

のinit FUNCに私の呼び出し:

init(5, desired_func); 

フルエラー: 'ボイド(my_type *)' から 'ボイド(*)(*ボイド)' に代入

互換性のないポインタ型線上

init関数で上記:

my_struct_t *my_str; 
my_str->funcp = my_funcp; 

答えて

4

関数ポインタの型を関数に合わせて変更します。 :

void (*funcp)(my_type *data); 

異なるシグネチャ(たとえば異なるパラメータタイプ)の関数を使用したい場合は、明示的なキャストを追加できます。例えば:desired_func関数(又はその署名funcp関数ポインタと一致していない他の機能)は、関数ポインタを介して呼び出される必要がある任意の時間は、関数ポインタをキャストしなければならないこと

init(5, (void (*)(void*)) desired_func); 

注関数を呼び出す前に元の型(この場合はvoid (*)(my_type*))に戻すか、未定義の動作を呼び出します。

別の(やや良好)別のこのようなdesired_func定義変更することである:(関数ポインタを介して、または直接的に)アドレスとして渡されるオブジェクトのタイプをdesired_funcを呼び出すときこと

void desired_func(void *vobj) { 
    my_type* obj = vobj; 
    /* rest of the code */ 
} 

注パラメータがmy_typeである必要があります。また、関数内でobjを参照解除する必要があります(アライメントがキャスト自体でも異なる場合は未定義の動作が呼び出されます)。

キャスト時に未定義のビヘイビアが発生する可能性があるため(前述のように)、キャストすることをアドバイスする必要があります。このようなキャストを必要とするのはおそらくデザイン上の問題を示しています。つまり要件をもう少し考えれば、おそらくもっと良い解決策があります。

+0

問題は、すべてのデータ型で動作する必要があることです。したがって、void * – bobbyyu10

+0

@ bobbyyu10:これも同様です。 –

+1

'void *'への変換はキャストを必要としないので、 'my_type * obj = vobj; 'で十分です。 – user3386109

関連する問題