データの受け渡しについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たくま

データの受け渡しについて

#1

投稿記事 by たくま » 18年前

はじめまして。
今、レジストリからデータを参照するプログラムを書いています。
そこで、main()とreg()間のデータがうまくやりとりできません…
ポインタとかの使い方がいまいちよくわからないせいなんですが…
プログラムも下記に載せておくので、もし間違いやおかしい点があればご教授をお願いします。
よろしくお願いします。

・プログラム
#include<windows.h>
#include<iostream>

char* reg(char path){
HKEY rKey;
LONG bRet;
char ValueName[256];
BYTE Data[256];
DWORD cbData;
DWORD dwType;
char d[256];
// レジストリキーハンドルを作成;
bRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
&path,
0, // 予約済み;
KEY_ALL_ACCESS, //キーに対す全ての操作を許可する。;
&rKey); // ここにキーハンドルが格納される。;

if( bRet != ERROR_SUCCESS ){
// 失敗
printf("RegOpenKeyEx");
exit(0);
}

// 値の読み込み;
cbData = sizeof(Data);
memset(Data, 0, cbData);
bRet = RegQueryValueEx( rKey, // オープンしているキーのハンドル;
"ProductName", // 読み取りたい値の名前を指定。;
NULL, //予約済み。NULLをいれること;
&dwType, // 値のデータの種類が入る。今回は不要なので, NULLにする。;
Data, // 情報が格納される。;
&cbData); // 情報のデータサイズ(Byte)を格納する。;
// 渡すときには情報を格納するバッファの大きさを入れておく。

if( bRet != ERROR_SUCCESS ){
// 失敗した。;
printf("RegQueryValueEx\n");
exit(0);
}

RegCloseKey(rKey);

return (char *)Data;
}
int main(){
char path[200]="SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
char *regstr;
regstr = reg((char)path);
printf("%s",regstr);
return 0;
}

Yuki

Re:データの受け渡しについて

#2

投稿記事 by Yuki » 18年前

変数pathはファイルパスの文字列が格納されているので、
以下のようにすれば、動くと思います。

>char* reg(char path){
char* reg(char *path){

>regstr = reg((char)path);
regstr = reg(path);

たくま

Re:データの受け渡しについて

#3

投稿記事 by たくま » 18年前

Yukiさん、ご回答ありがとうございます。
そのように変えて実行したら、出力が文字化けしてしまいます…
この場合は変数を定義する際にpathもポインタを使うんですよね?
char *path[200]="SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";のように。
こうすれば実行できるんですが、ここでポインタを使いたくないんです。
そんなことって出来ますか?

Justy

Re:データの受け渡しについて

#4

投稿記事 by Justy » 18年前

 reg()はローカル変数へのポインタを戻しています。
 reg()内の Data変数は関数を抜けた瞬間に無効になるので、main()が受け取った regstrポインタは無効です。

 main()で用意した文字列バッファのポインタに結果を入れるようにすれば解決すると思います。

たくま

Re:データの受け渡しについて

#5

投稿記事 by たくま » 18年前

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

>main()で用意した文字列バッファのポインタに結果を入れるようにすれば解決すると思います。
理解度が低くて申し訳ないんですが、regstrではなんでダメかがよくわかりません…

Justy

Re:データの受け渡しについて

#6

投稿記事 by Justy » 18年前

 まず原則として「関数内で宣言した変数は関数を抜けた瞬間に無効になる」ということです。
 つまり、reg()内で宣言した[color=#d0d0ff" face="monospace] BYTE Data[256][/color]という 256バイトのデータは returnで戻った後は消失します。
 残っているように見えても、ただの残骸でしかありません。

 main()の[color=#d0d0ff" face="monospace] regstr = reg(path);[/color]で受け取った regstrポインタが指している先は reg()内の Data変数のアドレスです。
 ですが、受け取った時にはその領域はゴミなのです。

 なので、1つの解決方法としては reg()を
[color=#d0d0ff" face="monospace]void reg(char *path, char *Data)[/color]
 のような形にして、戻り値を無くし、結果の出力先のポインタ Dataを追加します。
 その上で、ローカル変数として宣言していた Data変数を削除します。

 あとは main()の方を
[color=#d0d0ff" face="monospace]    char regstr[256]; 
    reg(path, regstr); [/color]
 とすれば、regstrに結果が入ります。

たくま

Re:データの受け渡しについて

#7

投稿記事 by たくま » 18年前

なるほど…
詳しくてわかり易い説明をしていただきありがとうございます。
しかも、なんとかできました。
Yukiさん、Justyさん、ご教授いただきありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る