プロが教える店舗&オフィスのセキュリティ対策術

perlのリファレンスはC言語のポインタのように実アドレスを示してないとの事。
では、例えば GetDiskFreeSpaceExのような、数値をポインタで受け取るような関数は、どのように使ったらよいのでしょうか。


use Win32::API;

my $DLL=new Win32::API('Kernel32', 'GetDiskFreeSpaceEx', 'PNNN', 'N');
my $n1=0;
my $n2=0;
my $n3=0;

my $rc=$DLL->Call('c:\\', \$n1, \$n2, \$n3);

これではエラーになります。。。。当然か。。。。

A 回答 (1件)

以下のようにしてください。


---------------------------------
my $GetDiskFreeSpaceEx =
new Win32::API(
"Kernel32", "GetDiskFreeSpaceEx","PPPP","N") || die;
my $p1 = pack("q",0);
my $p2 = pack("q",0);
my $p3 = pack("q",0);
my $ret = $GetDiskFreeSpaceEx->Call("c:\\",$p1,$p2,$p3);
if ($ret == 0){ die };
my $a1 = unpack("q",$p1);
my $a2 = unpack("q",$p2);
my $a3 = unpack("q",$p3);
print "Free=$a1 Total=$a2 TotalFree=$a3\n";
-----------------------------------------------------------
私の環境での実行結果です。
Free=853746626560 Total=920236060672 TotalFree=853746626560

GetDiskFreeSpaceExの第2、第3、第4パラメータは64ビット型符号なし整数へのポインター
になります。ですので、"PPPP"を指定します。
$p1,$p2,$p3が64ビットの符号なし整数を作成しています。
呼び出し後、unpackを行い、perlでそのまま扱える整数の$a1,$a2,$a3に変換しています。

私もWin32::APIを使用するのは初めてでしたので、念のためC言語でGetDiskFreeSpaceEx
を呼び出して、同一の値が取得できたことを確認しましたので、たぶん、あっているかと思います。
    • good
    • 0
この回答へのお礼

すばらしい回答、ありがとうございました。

残念なことに、私の環境では、pack("q",0) で、"q"がinvalidだと怒られてしまいましたが、ポインターの使い方という意味では、十分理解できました。感謝いたします。

お礼日時:2016/10/02 15:15

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!