Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Pesky warnings after calling Win32 API

by Biff (Novice)
on Sep 16, 2004 at 20:09 UTC ( #391557=perlquestion: print w/ replies, xml ) Need Help??
Biff has asked for the wisdom of the Perl Monks concerning the following question:

Greetings Monks,

I keep getting the following pesky little warning messages during an attempt to call the Win32 API GlobalMemoryStatus and I can't understand why.

C:\Documents and Settings\Owner\My Documents\GetInfo>test.pl

***BEFORE GMS

Use of uninitialized value in string eq at C:/Perl/site/lib/Win32/API/Struct.pm line 156, <DATA> line 164. Use of uninitialized value in numeric lt (<) at C:/Perl/site/lib/Win32/API/Struct.pm line 214, <DATA> line 164. Use of uninitialized value in numeric lt (<) at C:/Perl/site/lib/Win32/API/Struct.pm line 214, <DATA> line 164. Use of uninitialized value in numeric lt (<) at C:/Perl/site/lib/Win32/API/Struct.pm line 214, <DATA> line 164. Use of uninitialized value in numeric lt (<) at C:/Perl/site/lib/Win32/API/Struct.pm line 214, <DATA> line 164. Use of uninitialized value in numeric lt (<) at C:/Perl/site/lib/Win32/API/Struct.pm line 214, <DATA> line 164. Use of uninitialized value in numeric lt (<) at C:/Perl/site/lib/Win32/API/Struct.pm line 214, <DATA> line 164. Use of uninitialized value in numeric lt (<) at C:/Perl/site/lib/Win32/API/Struct.pm line 214, <DATA> line 164.

...

Use of uninitialized value in numeric lt (<) at C:/Perl/site/lib/Win32/API/Struct.pm line 268, <DATA> line 164. Use of uninitialized value in numeric lt (<) at C:/Perl/site/lib/Win32/API/Struct.pm line 268, <DATA> line 164.

***AFTER GMS

2097024 476436 30988 195568 84 2064472 186736

Actually I first noticed this while trying to use Win32::SystemInfo. The code below is cut from SystemInfo.pm. I've determined that the warnings come from the actual imported call to GlobalMemoryStatus.

Here's the code:

#!/usr/bin/perl -w use strict; use Data::Dumper; use Win32::API; #================== sub MemoryStatus (\%;$) { #================== # my $return = shift; #hash to return my $ret_type ||= shift || "B"; #what format does the user want? my %fmt_types = ( B => 1, KB => 1024, MB => 1024*1024, GB => 1024*1024*1024); my @params = qw(MemLoad TotalPhys AvailPhys TotalPage AvailPage TotalVirtual AvailVirtual); my %results; #results of fn call my $MemFormat; #divisor for format my $dwMSLength; #validator from fn call $MemFormat = ($ret_type =~ /^[BKMG]B?$/) ? $fmt_types{$ret_type} : $fmt_types{B}; # (See GlobalMemoryStatus on MSDN) # I had to change some of the types to get the struct to # play nicely with Win32::API. The SIZE_T's are actually # DWORDS in previous versions of the Win32 API, so this # change doesn't hurt anything. # The names of the members in the struct are different than # in the API to make my life easier, and to keep the same # return values this method has always had. Win32::API::Struct->typedef( MEMORYSTATUS => qw{ DWORD dwLength; DWORD MemLoad; DWORD TotalPhys; DWORD AvailPhys; DWORD TotalPage; DWORD AvailPage; DWORD TotalVirtual; DWORD AvailVirtual; }); Win32::API->Import('kernel32', 'VOID GlobalMemoryStatus(LPMEMORYSTA +TUS lpMemoryStatus)') or die "Could not locate kernel32.dll - SystemInfo.pm cannot contin +ue\n"; my $MEMORYSTATUS = Win32::API::Struct->new('MEMORYSTATUS'); print "***BEFORE GMS\n"; GlobalMemoryStatus($MEMORYSTATUS); print "***AFTER GMS\n"; return undef if $MEMORYSTATUS->{dwLength} == 0; if (keys(%$return) == 0) { foreach (@params) { $return->{$_} = ($_ eq "MemLoad") ? $MEMORYSTATUS->{$_} : $MEMORYS +TATUS->{$_}/$MemFormat; } } else { foreach (@params){ $return->{$_} = $MEMORYSTATUS->{$_}/$MemFormat unless (!exists($r +eturn->{$_})); } } 1; } my %mh; MemoryStatus(%mh,"KB"); foreach my $k (keys %mh) { print "$mh{$k}\n"; }
</readmore

janitored by ybiC: Balanced <readmore> tags around longish codeblock, as per Monastery convention

Comment on Pesky warnings after calling Win32 API
Download Code
Re: Pesky warnings after calling Win32 API
by ikegami (Pope) on Sep 16, 2004 at 22:32 UTC

    I don't know about the other members -- check the docs for GlobalMemoryStatus -- but dwLength must be initialized before GlobalMemoryStatus is called. I don't know if that'll help at all with the immediate problem, but I'm sure it's something you must do.

    The problem occures in Win32::API::Struct's getPack, in the line if($Win32::API::Type::PackSize{$type} < $align) {. I presume getPack prepares the perl structure into a C structure so that it can be passed to GlobalMemoryStatus.

    Update: After much digging in the sources, I found that you must call $MEMORYSTATUS->align('auto'). The following quote from the Win32::API::Struct pod is an understatement:

    But if you define your own structure, you may need to give it an explicit alignment. In most cases, passing a SIZE of 'auto' should keep the world happy.
      Thanks ikegami but that didn't fix the problem. I'm really freaked out by this cause I'm convinced that I'm doing something wrong but can't figure it out. Anyway, right now I'm just going to hide the warnings and get on with life. I hate doing this but I don't have much choice.

      Thanks for replying.

        So I decided to download Win32::API and run your code. My fix does indeed remove the warning at the line you mentioned. However, there are apparently more warnings, which are removed by the following:
        my $MEMORYSTATUS = Win32::API::Struct->new('MEMORYSTATUS'); { # Avoid warning at Struct.pm line 214 $MEMORYSTATUS->align('auto'); } { # Avoid all other warnings in Struct.pm $MEMORYSTATUS->{'dwLength' } = 0; $MEMORYSTATUS->{'MemLoad' } = 0; $MEMORYSTATUS->{'TotalPhys' } = 0; $MEMORYSTATUS->{'AvailPhys' } = 0; $MEMORYSTATUS->{'TotalPage' } = 0; $MEMORYSTATUS->{'AvailPage' } = 0; $MEMORYSTATUS->{'TotalVirtual'} = 0; $MEMORYSTATUS->{'AvailVirtual'} = 0; }

        I'd like to correct myself regarding dwLength. The docs say Windows will set it for you. Very odd.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://391557]
Approved by Old_Gray_Bear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (6)
As of 2014-12-21 10:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (104 votes), past polls