PostThreadMessageのパラメータ生存について – プログラミング – Home

通知
すべてクリア

[解決済] PostThreadMessageのパラメータ生存について


まさやん
 まさやん
(@まさやん)
ゲスト
結合: 12年前
投稿: 4
Topic starter  

MFCの勉強を始めたばかりですので、根本的に間違えているかもしれませんが
よろしくお願いいたします

PostThreadMessage発行時のパラメータについて教えていただきたいです

CDialogから派生のクラスで「AfxBeginThread」を使いスレッドを生成し、
スレッドへメッセージを投げる方法として以下のようにしてみました。

void xxx::yyy()
{
WPARAM wparam;
TRACE(スレッド送受信(WM_USER+1) 送信 \n);
wparam = (WPARAM)this->m_hWnd;
PostThreadMessage(etht_id, WM_USER +1, wparam, 0);
}

動作はしたのですが、以下の点教えていただきたいです
1、上記の「wparam」はメソッド抜けると消滅しますよ(違う?)
2、上記(1)前提で考えると「wparam」はメッセージを受けたスレッド側では保障され
ない事になる?
3、上記(2)前提で考えると、動作しているのはたまたまの偶然?

よろしくお願いいたします


引用未解決
トピックタグ
しま
 しま
(@しま)
ゲスト
結合: 18年前
投稿: 123
 

>1、上記の「wparam」はメソッド抜けると消滅しますよ(違う?)
Post した側の wparam は xxx::yyy() から抜けるとスタックフレームがなくなるので
消滅すると考えていいでしょう

>2、上記(1)前提で考えると「wparam」はメッセージを受けたスレッド側では保障さ
>れない事になる?
ポストメッセージの動作を考えれば分ることだと思います。
送信先のメッセージキューに送信したメッセージを溜めるのが
ポストメッセージなので相手にメッセーぞが残るわけです。
但し、メッセージとしてポインターがあって、送信元のスタック内のデーターを
指しているとうまくいかないことはお分かりだと思います。


返信引用
まさやん
 まさやん
(@まさやん)
ゲスト
結合: 12年前
投稿: 4
Topic starter  

早速の回答ありがとうございますm(__)m

>但し、メッセージとしてポインターがあって、送信元のスタック内のデーターを
>指しているとうまくいかないことはお分かりだと思います。
上記回答より以下のように理解しました。間違っていたらご指摘ください

1、今回の場合 「wparam」の中身は実在しているから動作している
(親スレッドなので消滅していない)

2、もし、「wparam変数自身のアドレス」を渡してしまうと、受け取ったスレッドでは処理
できない(アドレスが指す位置はすでに実態が消滅しているので保障できない)

3、上記(2)の事から、オブジェクトを渡す時などは、注意が必要で、スレッド側で処理
が終わるまでは存在を維持しておかないといけない

読んでみると、当たり前の事でした。お恥ずかしいw

ありがとうございました!
間違ってるよーて指摘が無いのを確認して「解決」にしたいと思います


返信引用
しま
 しま
(@しま)
ゲスト
結合: 18年前
投稿: 123
 

>2、もし、「wparam変数自身のアドレス」を渡してしまうと、受け取ったスレッドでは
>処理できない(アドレスが指す位置はすでに実態が消滅しているので保障できない)

wparam変数自身の番地に限らずです。
ポストした相手が処理できることこそが大切なのです。


返信引用
まさやん
 まさやん
(@まさやん)
ゲスト
結合: 12年前
投稿: 4
Topic starter  

連投すいません。

以下のようなコードはNGて事ですよねぇ

void xxx::yyy()
{
sMsg =(MSGDATA *)::GlobalAlloc(GPTR,sizeof(MSGDATA));

nPostRetV = PostThreadMessage(lID_SendRecvThread, WM_DATASEND, (WPARAM)sMsg, 0
);
if( !nPostRetV ) {
delete sMsg;
}
}

よろしくお願いいたします


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 18年前
投稿: 178
 

> sMsg =(MSGDATA *)::GlobalAlloc(GPTR,sizeof(MSGDATA));
>
> nPostRetV = PostThreadMessage(lID_SendRecvThread, WM_DATASEND, (WPARAM)sMsg, 0
>);
> if( !nPostRetV ) {
> delete sMsg;
> }

GlobalAlloc()したのならば、解放はGlobalFree()でしょう。
で、この場合だと動的確保した領域の生存期間はこの関数が実行されている間。というこ
とになりますので、メッセージを処理する時には解放済み。ということになってしまいます。

よって…NGです。


返信引用
まさやん
 まさやん
(@まさやん)
ゲスト
結合: 12年前
投稿: 4
Topic starter  

瀬戸っぷさん回答ありがとうございます

突っ込みは多々あるとは思いますが、パラメータの生存期間については理解できたと思いま
す。

ここまで回答していただいた、しまさん、瀬戸っぷさん、本当にありがとうございました
m(__)m
自信を持って先輩方に指摘できそうです

このスレは解決とさせていただきます。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました