2

関数ポインターの配列を関数に渡そうとしています。その関数に入ったら、その関数ポインターの配列へのポインターが必要ですが、エラーが発生し続けます。関数の引数でない場合はできます。

void (*(*PointerToFuncPtrArray)[2])(unsigned char data[], unsigned char length);
void (*FuncPtr[2])(unsigned char data[], unsigned char length) = {

    func1,
    func2,
}

void NotArguement(void)  // attempt to point to without passing as parameter
{
    PointerToFuncPtrArray = &FuncP;   // this works
}


//  attempt to pass as argument
void AsArguement((void (*ptr[])(unsigned char data[], unsigned char length))
{
   PointerToFuncPtrArray = &ptr;    // This throws error


}

これは...

Error   1   error C2440: '=' : cannot convert from 'void (__cdecl **[])(unsigned char [],unsigned char)' to 'void (__cdecl *(*)[2])(unsigned char [],unsigned char)'    
4

1 に答える 1

5

関数の引数リスト内の配列宣言は、ポインター宣言に崩壊します。そのため、関数パラメーターは配列として宣言されていません (誤解を招く外観にもかかわらず)。これはポインターツーポインターとして宣言されます。つまり、関数内で配列型が不可逆的に失われます。

この単純な例でも同じエラーが報告されます

int x[2];
...
void foo(int a[2]) /* <- equivalent to `void foo(int *a)` */
{
  int (*p1)[2] = &x; /* <- OK */
  int (*p2)[2] = &a; /* <- ERROR: can't convert `int **` to `int (*)[2]` */
}
...
foo(x);

上記の例aでは、配列ではなくなりました。これはint *type のポインターです。つまり、 type&aint **あり、 type のオブジェクトを初期化するために使用することはできませんint (*)[2]

C では、引数の「配列性」を維持しながら配列を関数に渡す唯一の方法は、次のように「配列全体へのポインターによって」渡すことです。

int x[2];
...
void foo(int (*a)[2])
{
  int (*p)[2] = a; /* <- OK */
}
...
foo(&x);

&演算子の適用が関数内から呼び出しのポイントに「移動」したことに注意してください。

コードの同じ変更は次のようになります

void AsArguement(void (*(*ptr)[2])(unsigned char data[], unsigned char length))
{
   PointerToFuncPtrArray = ptr;
}

&この関数を呼び出すときに、配列引数に演算子を適用することを忘れないでください。

于 2013-10-14T19:02:28.823 に答える