- ベストアンサー
プログラムが動かない!VC++
- プログラムが動かない理由を知りたい
- LPVIDEOHDRとは何を表しているのか教えて欲しい
- CCapture01DlgのFrameCallback関数内の処理内容について詳しく知りたい
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
★『m_lpData』ポインタはメモリを割り当てている? >どの行でプログラムが止まるかをデバッグしてみたところ >memcpy(m_lpData,lpVHdr->lpData,lpVHdr->dwBufferLength); >のところでプログラムが止まっている様子でした。 ↑ 『m_lpData』ポインタにメモリを確保して割り当てていなければ当然エラーです。 プログラムが止まって正常です。 >『image_b』、『image_g』、『image_r』のバッファ容量は大丈夫か? ↑ こちらは大丈夫のようだ。 >型はこれでは駄目なのでしょうか? ↑ 『型』は特に問題はないけど BYTE 型を使っているので合わせた方が見やすいかな。 >memcpy( m_lpData, lpVHdr->lpData, lpVHdr->dwBufferLength ); ↑ この行を memcpy( m_lpData, lpVHdr->lpData, (WIDTH * HEIGHT) ); としてみる。また m_lpData にもメモリを確保しないといけない。 ・でも今回は memcpy しなくていいと思いますけど。 つまり BYTE *pBuff; ←『LPBYTE pBuff』でも同じ指定 int i, j; pBuff = m_lpData; ←これだけで良い if ( pBuff != NULL ){ ←安全の為(*) for ( j = 0 ; j < HEIGHT ; j++ ){ for ( i = 0 ; i < WIDTH ; i++ ){ image_b[ i ][ j ]= *pBuff++; image_g[ i ][ j ]= *pBuff++; image_r[ i ][ j ]= *pBuff++; } } } return LRESULT(); ↑ これだけで上手くいくと思います。多分。 試して見て下さい。 ・以上。結果報告を待っています。
その他の回答 (5)
- Oh-Orange
- ベストアンサー率63% (854/1345)
★ソースファイルを調査すべき。 ・もう一度 (2)『m_lpData』のバッファ容量は大丈夫か? (5)『image_b』、『image_g』、『image_r』のバッファ容量は大丈夫か? をソースから探して調査して下さい。 多分、メモリ不足で実行時にエラーになっていそうです。補足を見ると。 ・あと (3)定数?変数?の『WIDTH』と『HEIGHT』は固定に見えるが『lpVHdr->dwBufferLength』と 一致するのか?不一致で『lpVHdr->dwBufferLength』が大きいなら実行時にエラーで決定。 ↑ これは次の方法でチェックして下さい。 // グローバル変数を用意 static BOOL bCheck = FALSE; // コールバック関数 LRESULT PASCAL CCapture01Dlg::FrameCallback( HWND hWnd, LPVIDEOHDR lpVHdr ) { if ( lpVHdr->dwBufferLength > (HEIGHT * WIDTH) ){ bCheck = TRUE; } return LRESULT(); } ↑ コールバック関数が実行された後に自前で用意していた bCheck 変数をチェックして TRUE になっていればバッファ容量オーバーとなり→実行時エラーの原因決定です。 ・それでは調査結果を待っています。
補足
LRESULT PASCAL CCapture01Dlg::FrameCallback( HWND hWnd, LPVIDEOHDR lpVHdr ) { if ( lpVHdr->dwBufferLength > (HEIGHT * WIDTH) ){ bCheck = TRUE; } return LRESULT(); } ↑ bCheckはTRUEになっていました。 どの行でプログラムが止まるかをデバッグしてみたところ memcpy(m_lpData,lpVHdr->lpData,lpVHdr->dwBufferLength); のところでプログラムが止まっている様子でした。 『m_lpData』のバッファ容量は大丈夫か? 『image_b』、『image_g』、『image_r』のバッファ容量は大丈夫か? ですが、それぞれの宣言はstdafc.hというヘッダーに次のように宣言しています。 static BYTE *m_lpData; static unsigned char image_r[WIDTH][HEIGHT]; static unsigned char image_g[WIDTH][HEIGHT]; static unsigned char image_b[WIDTH][HEIGHT]; 型はこれでは駄目なのでしょうか? ちなみにWIDTH、HEIGHTは#define定義でそれぞれ320、240としています。
- Oh-Orange
- ベストアンサー率63% (854/1345)
★エラー場所を特定しましょう。 >エラーというのはプログラムをビルドして実行すると途中で >プログラムが止まってしまうというエラーです。 ↑ これはビルドは成功したが実行時に期待する動作にならないと考えていいのか? まずはどの関数が原因で止まるのか調査して下さい。 次の5つを確認して下さい。 (1)質問の関数を実行したときに途中で止まるのか? (2)『m_lpData』のバッファ容量は大丈夫か? (3)定数?変数?の『WIDTH』と『HEIGHT』は固定に見えるが『lpVHdr->dwBufferLength』と 一致するのか?不一致で『lpVHdr->dwBufferLength』が大きいなら実行時にエラーで決定。 (4)『i』と『j』カウンタが横と縦なので『image_b[横][縦]』という意味で良いのか? 普通の二次配列の使い方からすると『image_b[縦][横]』が一般ですけど。これでいいの? (5)『image_b』、『image_g』、『image_r』のバッファ容量は大丈夫か? ・上記の5つを調べてみて下さい。 あと実行時にプログラムが止まるようですが『無反応』で止まるのですか? それともエラーダイアログなどが表示されますか? 表示される場合はどんなメッセージか? ・以上。いろいろ補足要求します。
補足
>これはビルドは成功したが実行時に期待する動作にならないと考えていいのか? ↑ はい、ビルドは成功して実行時に強制的に中断される感じです。 >(1)質問の関数を実行したときに途中で止まるのか? はい。質問のFrameCallback関数が実行されたときです。 ちなみにこの前デバックをしてみた感じmemcpy(m_lpData,lpVHdr->lpData,lpVHdr->dwBufferLength);のところで止まってしまってるようでした。 >(2)『m_lpData』のバッファ容量は大丈夫か? すみませんわかりません。 >(3)定数?変数?の『WIDTH』と『HEIGHT』は固定に見えるが『lpVHdr->dwBufferLength』と 一致するのか?不一致で『lpVHdr->dwBufferLength』が大きいなら実行時にエラーで決定。 「WIDTH」と「HEIGHT」は自分が決めた定数です。ちなみに「WIDTH」は320、「HEIGHT」は240と定義しています。 『lpVHdr->dwBufferLength』と一致するかどうかはすみませんわかりません。 >(4)『i』と『j』カウンタが横と縦なので『image_b[横][縦]』という意味で良いのか? 普通の二次配列の使い方からすると『image_b[縦][横]』が一般ですけど。これでいいの? はい。『image_b[横][縦]』という意味です。 Bitmap構造においてデータを格納する際、下から横一列を順番に配列データに格納していくらしいのですが、この自分がやったやり方は間違いなのでしょうか? >(5)『image_b』、『image_g』、『image_r』のバッファ容量は大丈夫か? 容量が大丈夫かどうかというのはすみませんわかりません。でももしかしたら足りてないのかもしれません。 曖昧な回答しかできなくて本当にすみません。 最後に実行時に表示されるエラーダイアログなどは他の補足のところに載せておきました。
- aris-wiz
- ベストアンサー率38% (96/252)
> エラーというのはプログラムをビルドして実行すると途中で > プログラムが止まってしまうというエラーです。 コンパイルで失敗しているなら、 そのエラーをコピー&ペーストしてください。 ついでに環境をもう少し明確に出来ると良いと思います。 >LPVIDEOHDR ここではVIDEOHDR構造体のポインタとしてtypedefされています。 MSの命名規則みたいなもので、構造体や独自の型のポインタに対して、 LP(ロングポインタの略称)を、つけているものです。 自分で書くと以下のような感じになります typedef struct list{ size_t size; void *data; struct list* next; }LIST, *LPLIST: ~~~~~~~~~~~~~~~~
補足
ビルドし、実行を行ってる最中に下のようなダイアログが出てきて 「中断」か「続行」してくださいとなります。 ↓ダイアログメッセージ↓ 「Capture01.exe の 0x10231f1a (msvcr80d.dll) でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000000 に書き込み中にアクセス違反が発生しました。」 そして中断をし、ビルド停止を行うと下のmemcpy.asmというところが表示され矢印を書いたとこ(下から4行目)に矢印が現れます。 memcpy.asm Dword_align: test edi,11b ;U - destination dword aligned? jnz short CopyLeadUp ;V - if we are not dword aligned already, align shr ecx,2 ;U - shift down to dword count and edx,11b ;V - trailing byte count cmp ecx,8 ;U - test if small enough for unwind copy jb short CopyUnwindUp ;V - if so, then jump (ココ⇒)rep movsd ;N - move all of our dwords jmp dword ptr TrailUpVec[edx*4] ;N - process trailing bytes ;
- Oh-Orange
- ベストアンサー率63% (854/1345)
★アドバイス >その3行は >image_bを*pBuffに、image_gを*pBuffの隣の*(pBuff+1)に、 >そしてimage_rを*(pBuff+1)の隣の*(pBuff+2)というところに >それぞれ格納していると考えています。 ↑ これなら image_b[ i ][ j ]= *pBuff++; image_g[ i ][ j ]= *pBuff++; image_r[ i ][ j ]= *pBuff++; の3行で良いでしょう。 ・『pBuff++』でポインタを移動していますので『*(pBuff + 1)』とか『*(pBuff + 2)』は 必要ありません。やるとポインタがさらに次のピクセル情報に移動していまいずれます。 上記の3行を直せば期待通りになりませんか。 ・『LPVIDEOHDR』は『VIDEOHDR』構造体のポインタの型ですけど。 capVideoStreamCallback() というコールバック関数で渡される構造体のようです。 あまり詳しくないので MSDN サイトの次のリンクを参考にして下さい。 http://msdn2.microsoft.com/en-us/library/ms713472.aspx http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpmltimd/html/_win32_capvideostreamcallback.asp ・以上。
お礼
Oh-Orangeさん回答ありがとうございます。 LPVIDEOHDRは何となくですがわかりました。 >image_b[ i ][ j ]= *pBuff++; >image_g[ i ][ j ]= *pBuff++; >image_r[ i ][ j ]= *pBuff++; 上のようにしても同じ結果のエラーがでます。 エラーというのはプログラムをビルドして実行すると途中で プログラムが止まってしまうというエラーです。 もしかしたら配列のメモリを動的に確保すればいいのでしょうか? もしこのプログラムで動的なメモリ確保を行うにはどうすればよい のでしょうか?
- morigann
- ベストアンサー率17% (57/329)
何がどううまく動かないのかよくわかりませんが・・・ 以下の3行おかしくないでしょうか? image_b[i][j]= *pBuff; pBuff++; image_g[i][j]= *(pBuff+1); pBuff++; image_r[i][j]= *(pBuff+2); pBuff++; imageに代入した後に++を行っているのであれば、pBuffの「+1」や「+2」って必要でしょうか? 何が正常かよく分からないですが、気になったのでご参考までに・・・
補足
morigannさん返事ありがとうございます。 プログラムは学び始めなので間違っているのかも知れませんが その3行は image_bを*pBuffに、image_gを*pBuffの隣の*(pBuff+1)に、 そしてimage_rを*(pBuff+1)の隣の*(pBuff+2)というところに それぞれ格納していると考えています。 説明不足ですみません。 ちなみにやろうとしていることはWebカメラ等から得たキャプチャー データを配列に格納するという画像処理です。
補足
『m_lpData』ポインタにメモリを下のように確保して割り当ててみました。 BYTE m_lpData1[WIDTH*HEIGHT*3]; ←ヘッダーファイル内に定義 m_lpData=m_lpData1; ←FrameCallback関数内で定義 Oh-Orangeさんの指摘どうりただ単に『m_lpData』ポインタにメモリを確保して割り当てていなかったからエラーでプログラムが止まっていたようでした。ありがとうございます。 ちなみに上で定義宣言した『m_lpData1[WIDTH*HEIGHT*3]』は大丈夫でしょうか?何か変だなと感じられましたら教えてください。 『m_lpData1[WIDTH*HEIGHT*3]』の最後の3はr,g,bの3色あるということ(『image_b』、『image_g』、『image_r』)から3倍をつけてみました。 前回書いて頂いた int i, j; pBuff = m_lpData; ←これだけで良い if ( pBuff != NULL ){ ←安全の為(*) for ( j = 0 ; j < HEIGHT ; j++ ){ for ( i = 0 ; i < WIDTH ; i++ ){ image_b[ i ][ j ]= *pBuff++; image_g[ i ][ j ]= *pBuff++; image_r[ i ][ j ]= *pBuff++; の方はまだ試していません、すみません。今度試してみます。