CStringとLPBYTEのデータ – プログラミング – Home

通知
すべてクリア

[解決済] CStringとLPBYTEのデータ

固定ページ 1 / 2

ちか
 ちか
(@ちか)
ゲスト
結合: 20年前
投稿: 35
Topic starter  

VisualStudio2005 MFCでの開発です。

すでに作成してあるプログラムで、LPBYTE型の文字を使用して処理を行っているのです
が、その途中で一部分を抜き出したLPBYTE型にする・・という機能を追加しています。

追加した機能では、LPBYTE型の文字列がはいっているデータをうけとり、
一部分を抜き出したものをCString型の変数に入れました。

その後、CString型の文字列をLPBYTE型の変数におきかえてあげるにはどうすればいいの
でしょうか。

(もともとのプログラムのLPBYTE型データから一部分を抜き出したLPBYTE型を渡して
 そのまま処理を行わせたいのです)

初心者のため、表現方法が適切ではないかもしれません。
宜しくお願いします。


引用未解決
トピックタグ
+
 +
(@ )
ゲスト
結合: 17年前
投稿: 50
 

BYTE ch[] = abcd;
LPBYTE x = ch ;
CString str;

str = (LPCTSTR)x;


返信引用
ちか
 ちか
(@ちか)
ゲスト
結合: 20年前
投稿: 35
Topic starter  

+さん、回答ありがとうございます。

すみません。書き方が悪かったようです。
CString型への変更はできたのですが、
できあがったCStringの変数の中身をLPBYTEに渡してあげたいのです。

+さんの例のあとに、strの中身を変更したものを、再度xに渡してあげる
ということは可能でしょうか。


返信引用
+
 +
(@ )
ゲスト
結合: 17年前
投稿: 50
 

むぅ。。。。
TCHARに変換した後、どうするかによる。

TCHARに変換した後、文字列操作しないなら。
CString str;
TCHAR x = (TCHAR)(LPCTSTR)str;//無理やりバージョン

TCHARに変換した後、文字列操作するなら。
CString str;
TCHAR x = str.GetBuffer(str.GetLength() + 1);
::strcat(x,0123);
str.ReleaseBuffer();//だったかな?


返信引用
+
 +
(@ )
ゲスト
結合: 17年前
投稿: 50
 

TCHARじゃなかった。LPBYTEと読み替えてね^^;
コンパイラに叱られたらキャストを。。。


返信引用
Blue
 Blue
(@Blue)
ゲスト
結合: 20年前
投稿: 1467
 

とりあえず、

>LPBYTE型の文字
とは?
文字コードはShift_JISなのか?Unicodeなのか?

また、LPBYTE型の文字列の領域は誰が面倒みるのか?
CStringT::GetBufferではCString変数が寿命が尽きると使えなくなります。


返信引用
ちか
 ちか
(@ちか)
ゲスト
結合: 20年前
投稿: 35
Topic starter  

+さん、度々ありがとうございます。
無理やりバージョンのほうで、なんとかデータをLPBYTEに移すことはできたのですが、
引き続き伺いたいことがあります。

-----------------------------------------------------------
-----------------------------------------------------------
AAA::BBB( LPBYTE x ) { //この時点でxに文字が入っている
CCC ( x );
}

AAA::CCC ( LPBYTE x ) {
xの文字を操作し、変更した内容でxに入れてあげる
}
-----------------------------------------------------------
-----------------------------------------------------------
↑のようなことを行っており、AAA::CCCの中で、xに変更した値が入っていることを
デバッグで確認しました。
ただ、呼ばれた先(AAA::BBB)に戻ったときにxの値が元の値(AAA::CCCに入る前)
に戻ってしまいます。

CCC ( &x ) とするとコンパイルで
「error C2664: ~ 1 番目の引数を 'LPBYTE *__w64 ' から 'LPBYTE' に変換できませ
ん」とエラーが出てしまいます。

全くの素人のような質問で申し訳ありません・・。


返信引用
ちか
 ちか
(@ちか)
ゲスト
結合: 20年前
投稿: 35
Topic starter  

Blueさん、
文字コードはShift_JIS です。

>また、LPBYTE型の文字列の領域は誰が面倒みるのか?
この質問の回答ですが、すみません・・。理解不足で回答ができません。

行っていることは+さんへの変身に書いたようなことです。
(すでにAAA::BBBに引数として渡されている)

アドバイスなどあればよろしくお願いいたします。


返信引用
chamaro
 chamaro
(@chamaro)
ゲスト
結合: 17年前
投稿: 19
 

呼び元で領域をちゃんと確保していないと、バッファーオーバーフローしそうです
が・・・


返信引用
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

AAA::CCC ( LPBYTE x )で、
以下のどちらを行っているかによる。

x[0] = 'a';
x = a;

後者はxの内容を変えているわけじゃないので
変わりません。

LPBYTEは好きではないのでBYTEで書きますね。

AAA::CCC ( BYTE** x );
ならば
CCC(&x)と書けるようになる。

しかし
他の方が指摘しているように
文字列を格納するメモリを誰が確保して誰が解放するのかが
ごっちゃになって動作しなくなりますよ。


返信引用
wclrp ( 'o')
 wclrp ( 'o')
(@wclrp ( 'o'))
ゲスト
結合: 18年前
投稿: 287
 

AAA::CCC ( LPBYTE x )で、
x[0]='a';
x[1]='b';
みたいなことをするなら
x[n]のnはいくつまで使用可能か分かっている上で行わないといけません。

バイト数が増える可能性があるなら
AAA::CCC ( LPBYTE x )では無理ですね。

AAA::CCC ( BYTE** x )にした場合
x = new BYTE[増やしたサイズ];
とすると、もともとのxは
- 解放してはいけない
- freeしなければいけない
- deleteしなければいけない
のどれなのか不明である。

それと
大本のCString str;のstrは変わらないので
AAA::BBB( BYTE** x )も変えて
・・・
あーメンドクセ
AAA::BBB( std::vector<BYTE>& x );
AAA::CCC( std::vector<BYTE>& x );
こうしちゃえよ。
でも、これで上手く行くのかは知りません。

C/C++の文字列って面倒だな。


返信引用
ちか
 ちか
(@ちか)
ゲスト
結合: 20年前
投稿: 35
Topic starter  

chamaroさん、ご指摘ありがとうございます。
勉強不足で、現状の動きをおいかけるのがやっとの状態のため
そこまで気がまわっていませんでした。

もう少し、他の方の回答も参考に見直しをしてみます。


返信引用
ちか
 ちか
(@ちか)
ゲスト
結合: 20年前
投稿: 35
Topic starter  

wclrp ( 'o')さん、めんどくさいことをありがとうございます。

なかなかやっかいそうですね。。
教えていただいた方法を試しつつ、
他の手段がないかを検討してみます。

ひとまず、解決済みとします。
ありがとうございました。


返信引用
rin
 rin
(@rin)
ゲスト
結合: 18年前
投稿: 112
 

時間がゆるすなら、一度今の作業をストップさせて、
「ポインタ」を勉強したほうがいいと思う

まず
「LPBYTE型の文字列」
これがおかしい。

かなり大雑把にすすめますが

LPBYTE型は、扱いたいデータ本体ではなく、
データが保持されている場所を示すものです。

+さんの書かれた例でいえば

BYTE ch[] = abcd; ←このchが文字列の本体。
LPBYTE x = ch ;   ←chが保存されている場所を示す情報をxに入れておくだけ

つまり、
x自体が[abcd]を持ってるわけじゃないし、
chのサイズやその生存期間を、xからは管理できない。
開放などして、chがなくなってしまったりすると、
xの値が入ったままだとしても、その情報は意味が無くなります。

例えて書くと
abcd 住人
ch[] 家そのもの
x 住所
こんな感じ

んでもって
==============================
AAA::BBB( LPBYTE x ) { //この時点でxに文字が入っている
CCC ( x );
}
AAA::CCC ( LPBYTE x ) {
xの文字を操作し、変更した内容でxに入れてあげる
}
==============================
これだが、
まず、CCC(LPBYTE x)のxは、CCC内だけで通じるローカルの変数でしかなく、
BBBのxとは別物です(CCCのほうをyに変えても成立するでしょ)。
BBBから呼ばれるときに、「住所情報」を貰ってるだけです

その上で、CCC内でxに何かの値を上書きするということは
「別の住所」が上書きされるということになります。
ここでは「住所情報」が失われるだけで大元の文字列はなんら変更されないのです。

ウォッチなどをみると、xは「新しく上書きされた別の住所」
を示しますから、CCC内のxでは情報が更新されてみえますが、
BBBに戻ったとき、BBBのxが指し示す住所は変わってないため、
値が戻ったように見えるのです

で、最後に
wclrp ( 'o')さんが書かれているのが
「xが指し示す大元のデータにアクセスする」方法。
これをつかえば、大元のデータが変更できます。

#間違いがあったら指摘お願いいたします


返信引用
二
 二
(@二)
ゲスト
結合: 17年前
投稿: 4
 

自分ならきっとこんな実装するだろう。
つまり、BBB関数のへ入る前と後では、xは別物にする。

//この時点でxに文字が入っている
⇒xは誰かがnewしてるハズと(勝手に)仮定ww
void AAA::BBB( LPBYTE x )
{
x = CCC ( &x );
}

LPBYTE AAA::CCC ( LPBYTE *tmp )
{
//xの文字を操作し、変更した内容でxに入れてあげる
⇒ってことは文字の長さが短くなるのかな?まぁいいや

(略)

int newLength = strlen( 新しい文字 );

PBYTE ret = new BYTE [newLength];
memcpy( ret , 新しい文字 , newLength );

delete [] *tmp;//仮定が外れてるならキケンな香りww

return ret;
}


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

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