- ベストアンサー
void*型の配列について
void* a[2]; void* b = a; void* c[2] = (void *[2])b; error C2440: '型キャスト' : 'void *' から 'void *[2]' に変換できません。 配列型への変換はありませんが、参照またはポインタから配列への変換があります。 void*型にした a を再度void*型の配列に戻すにはどのように記述すればよいでしょうか? 環境はXP(SP3)のVS2008 MFC です。 宜しくお願いいたします。
- みんなの回答 (8)
- 専門家の回答
質問者が選んだベストアンサー
void* a[2]; void* b; void* (*c)[2]; b = (void*)a; c = (void* (*)[2])b; ってことですか?
その他の回答 (7)
- Tacosan
- ベストアンサー率23% (3656/15482)
void* p[2]; のとき p の型は void *[2] であり, これに対して配列からポインタへの変換を適用すると void ** となります. だから AfxBeginThread の呼び出しを今のままにするなら, barThread の中では bar((void **)p); のようにキャストすれば十分だし, 受け取る bar の方も void bar(void **p) { HANDLE handle = *(HANDLE*)p[0]; HANDLE event = *(HANDLE*)p[1]; // 以下略 } でいいはず. 逆に, bar を今のままにするなら foo における AfxBeginThread の呼び出しを AfxBeginThread(barThread, &p); としないと本来はアウト.
お礼
勉強になりました。ありがとうございました。
補足
そうですね。仰られる通り、 void bar(void **p) とし、 *(HANDLE*)p[0]; とするのが自然ですね。
- m-take0220
- ベストアンサー率60% (477/782)
AfxBeginThreadの引数等がLPVOIDというのが引っかかってるんでしょうか? handleとeventは、変更する必要はなさそうなんですが。変更しないのであれば、ポインタにする必要もないので、 HANDLE h[2] = {handle, event}; AfxBeginThread(bar, (LPVOID)h); として、 void bar(LPVOID p) { HANDLE* ph = (HANDLE*)p; HANDLE handle = ph[0]; HANDLE event = ph[1]; ... } でいいような気がしますが。
補足
すみません。例が良くなかったですね。 ポインタにする必要がある場合と仮定していただけると幸いです。 お手数おかけしてすみません。
- hrsmmhr
- ベストアンサー率36% (173/477)
キャストしますか? やっぱりダブルポインタでしょうか? ひょっとしたらvoid*()[]で通るかもしれませんが 少なくとも配列の長さは入れても意味がないと思います。
お礼
勉強になりました。ありがとうございました。
補足
void* a[2]; void** b = a; void* c[2] = (void*()[])b; ということでしょうか? error C2090: 関数は配列を返せません。 error C2066: 関数型へのキャストが正しくありません。 error C2440: '初期化中' : 'void **(__cdecl *)(void)' から 'void *[2]' に変換できません。 配列型への変換はありませんが、参照またはポインタから配列への変換があります。 となりました。 ダブルポインタです。 キャストはしなくてもよい気はしています。 なんだかふわふわした質問ですみません...
- Tacosan
- ベストアンサー率23% (3656/15482)
余談ですが void *a[2]; void *b; void *(*c)[2]; とすると void *(*)[2] は c の型であり, 同時に &a の型でもあります. したがって上の場合 c = &a; は文法的に全く正当です. 見た人間は驚くかもしれませんが. なお 「仮にキャストしたい場合はどのようにしたらよいかありますでしょうか?」 についてはどういう場面を想定しているかわからないのでパス. どういう式でどこにキャストを明示するときの話かが分かれば方法を書くかも.
補足
使用例は、 void bar(void*(*p)[2]) { ULONG addr = 0x10; ULONG data = 0; HANDLE handle = *(HANDLE*)(*p)[0]; HANDLE event = *(HANDLE*)(*p)[1]; while(data == 0){ read(handle, addr, &data); } SetEvent(event); } UINT barThread(void* p) { bar((void*(*)[2])p); return 0; } void foo(HANDLE handle, HANDLE event) { void* p[2]; p[0] = &handle; p[1] = &event; AfxBeginThread(barThread, p); } のような感じです。 キャストを明示的にする意味はあまりなさそうですかね...
- m-take0220
- ベストアンサー率60% (477/782)
(void* (*)[2])はvoid* [2]へのポインタです。 void* c[2];とすると、cはaと同じくvoid*の配列になるので、代入することができません。 なので、ポインタにしています。 そもそも、cをどのように使用したいのでしょうか?
補足
(void* (*)[2])の意味はなんとなくわかるのですが、もっと深く知りたかったのでお聞きしました。 使用例は、 void bar(void*(*p)[2]) { ULONG addr = 0x10; ULONG data = 0; HANDLE handle = *(HANDLE*)(*p)[0]; HANDLE event = *(HANDLE*)(*p)[1]; while(data == 0){ read(handle, addr, &data); } SetEvent(event); } UINT barThread(void* p) { bar((void*(*)[2])p); return 0; } void foo(HANDLE handle, HANDLE event) { void* p[2]; p[0] = &handle; p[1] = &event; AfxBeginThread(barThread, p); } のような感じです。
- Tacosan
- ベストアンサー率23% (3656/15482)
void *a[2]; void *b = a; void **c = b; ということ?
補足
すみません。回答いただいてから気がつきました。 void* b = a; ではなく、 void** b = a; が正しいですね。 キャストしなくても良いようですね・・・ 仮にキャストしたい場合はどのようにしたらよいかありますでしょうか?
- hrsmmhr
- ベストアンサー率36% (173/477)
二行目の式でaはvoidのダブルポインタなので bはvoidのダブルポインタの型でないといけなくて そうすればcはキャストしないでもよいのではないでしょうか?
補足
すみません。回答いただいてから気がつきました。 void* b = a; ではなく、 void** b = a; が正しいですね。 キャストしなくても良いようですね・・・ 仮にキャストしたい場合はどのようにしたらよいかありますでしょうか?
お礼
Tacosan様の以下と合わせて理解できました。ありがとうございました。 --- void *a[2]; void *b; void *(*c)[2]; とすると void *(*)[2] は c の型であり, 同時に &a の型でもあります. したがって上の場合 c = &a; は文法的に全く正当です. ---
補足
すみません。回答いただいてから気がつきました。 void* b = a; ではなく、 void** b = a; が正しいですね。 で、すみません、 void* (*) はどのような意味なのでしょうか? 参考になるURLなど教えていただけませんか? 呼び方がわからないので検索できませんでした。