2

これは OpenCL チュートリアルからのものです。私は持っている:

void* args[4] = {(void*)5, (void*)123, NULL, NULL}; 
cl_mem mem_list[2] = {mem_d1, mem_d2}; // mem_d1 and mem_d2 are cl_mem objects
void* args_mem_loc[2] = {&args[2], &args[3]};
status = clEnqueueNativeKernel(*queue, nativeKernel, args, 4, 2, mem_list, args_mem_loc, 0, NULL, NULL); // http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clEnqueueNativeKernel.html

コンパイラ エラーが発生し続けます (status = clEnqueueNativeKernel(*queue... の行で、それが話しているパラメーターは args_mem_loc です)。

error C2664: 'clEnqueueNativeKernel' : cannot convert parameter 7 from 'void *[2]' to 'const void **'

args_mem_loc は void ポインターの配列への void ポインターであり、それが使用するすべての変数はスタック上に作成されます (そうですか? 私はかなり確信しています)。では、なぜコンパイラはそれを void* [2] と見なすのでしょうか?

4

2 に答える 2

3

これ:

void* args_mem_loc[2] = {&args[2], &args[3]};

暗黙的にこれに変換します。

void **

これは暗黙的にこれに変換できません:

const void **

const void *aを a に代入してvoid *const の正確さを破ることができるからです。

コンパイラは、それがそれでargs_mem_locあるvoid *[2]ためです。に暗黙的に変換できる配列を渡したい場合はconst void **、 として宣言args_mem_locconst void *arg_mem_loc[2]= {...};ます。

ちなみに、const void **その関数のパラメータはconst void * const *; その場合、暗黙的な変換が機能します。これは、そのポインターを介して代入することは違法であるため、関数が変更されないことを示し、args_mem_locしたがって暗黙的な変換が許可されます。

于 2013-08-21T18:21:28.447 に答える
1

配列へのポインターがvoid* args_mem_loc[2]ある場合は、別のポインター自体ではなく、ポインターの配列を指すポインターがあることを意味します。args_mem_locしたがって、基本的に、ポインターへのポインターとして渡すには、次を使用する必要があります。

&args_mem_loc[0]

また

&args_mem_loc[1]

次に、別のポインター (配列の各スロットにあるもの) を指すポインター (void* から) を取得します。

于 2013-08-21T18:05:05.120 に答える