by Hippo2000(Aug 30th, 2000)
The Win32::API module allows you to call DLLs
from Perl.
So, I will introduce how to use UNLHA32.DLL with that module.
To call DLL, you can use Win32::API module. It may be included in standard distribution.
| Packages | Description |
|---|---|
| Win32::API | Implementation of arbitrary Win32 APIs. |
Before you can call DLL, you should do 2 steps.
(1)Creating a Win32::API object(Function Declaration)
(2)Calling that function
(1) Create a Win32::API Object:$oNewAPI = new Win32::API($library, $functionname, \@argumenttypes, $returntype);(2)Calling that function:$return = $oNewAPI->Call(@arguments);
\@argumenttypes and $returntype are specified with these characters:
Type Char Type N Numeric?iLONG? I Numeric?iInteger? P Other?iStrins?AStruct and so on?
ex. Declarations for UnlhaGetVersion, UnLha functions of UNLHA32.DLL in VB
Declare Function UnlhaGetVersion Lib "unlha32" () As IntegerDeclare Function Unlha Lib "unlha32"_ (ByVal hwnd As Long, ByVal szCmdLine As String, _ ByVal szOutput As String, ByVal dwSize As Long) As Long
same declarations in Perl :
$GetVer = new Win32::API("unlha32", "UnlhaGetVersion", [], I); $nRes = $GetVer->Call(); $nRes &= 0xFFFF; #only last 2bytes (for Integer)$Lha = new Win32::API("unlha32", "Unlha", [N, P, P, N], N); $sBuff = "\x00" x 2000; #Buffer allocatioin (2000 has no special meanings) $nRes = $Lha->Call(0, 'a -rx c:\\kabaya.lzh "c:\\My Documents\\" *.htm', $sBuff, 2000); $sBuff =~ s/\x00+$//; #Truncate
And you can use pack and unpack to set or get datas from/to Structures.
Sample programming for compressing, uncompressing, file listing with UNLHA32.DLL
use File::Path; #Only for remove files (not required for UNLHA) use Win32::API; #1. Get Version information # Function Declaration my $GetVer = new Win32::API("unlha32", "UnlhaGetVersion", [], I); $nRes = $GetVer->Call(); $nRes &= 0xFFFF; #get last 2 bytes (for int) # print "Ver: $nRes\n"; #2.Get file count # Function Declaration my $GetF = new Win32::API("unlha32", "UnlhaGetFileCount", [P], N); my $nCnt = $GetF->Call('c:\\tt1.lzh'); print "Count: $nCnt\n"; #3.LHA Commands # Function Declaration $Lha = new Win32::API("unlha32", "Unlha", [N, P, P, N], N); #(1)Compress #Compress htm files, searching under "c:\My Documents" recursively unlink('c:\\kabaya.lzh'); $sBuff = "\x00" x 2000; #Buffer allocation $nRes = $Lha->Call(0, 'a -rx c:\\kabaya.lzh "c:\\My Documents\\" *.htm', $sBuff, 2000); $sBuff =~ s/\x00+$//; #truncate 0x00s print $sBuff, "\n"; #(2)Uncompress rmtree('c:\\lhaext\\'); #remove files under "c:\lhaext" recursively mkdir('c:\\lhaext', 0777); $sBuff = "\x00" x 2000; #Buffer allocation $nRes = $Lha->Call(0, 'x c:\\kabaya.lzh c:\\lhaext\\', $sBuff, 2000); $sBuff =~ s/\x00+$//; #truncate 0x00s print $sBuff, "\n"; #4.Process wit OpenArc my $lhaOpenArc = new Win32::API("unlha32", "UnlhaOpenArchive", [N, P, N], N); my $lhaFindFirst = new Win32::API("unlha32", "UnlhaFindFirst", [N, P, P], N); my $lhaFindNext = new Win32::API("unlha32", "UnlhaFindNext", [N, P], N); my $lhaCloseArc = new Win32::API("unlha32", "UnlhaCloseArchive", [N], N); #4.1 Open my $nArc = $lhaOpenArc->Call(0, "c:\\kabaya.lzh", 0); #4.2 FindFirst $oPack= "\x00" x 558; my $nRes = $lhaFindFirst->Call($nArc, "*", $oPack); while($nRes ==0) { #unpack structure ($nSize, $nCmpSize, $nCrc, $nUFlag, $nOStype, $iRatio, $iDate, $iTime, $sFileName, $sDummy, $sAttr, $sMode) = unpack("LLLLLSSSa513a3a8a8", $oPack); $sFileName =~ s/\x00+$//; #truncate 0x00s print "File:$sFileName SIZE:$nSize -> $nCmpSize (", $iRatio / 10, ")\n"; #Formating (date, time) $iNen = (($iDate>>9) & 127) + 1980; # Top 7 Bits : Years from 1980 $iTuki = ($iDate>>5) & 15; # Next 4 Bits : Months $iHi = $iDate & 31; # Last 5 Bits : Days $iHour = ($iTime>>11) & 31; # Top 5 Bits : Hours $iMin = ($iTime>>5) & 63; # Next 6 Bits: Minutes $iSec = ($iTime & 31) * 2; # Last 5 Bits: Seconds / 2 # printf " Date:%4d/%2d/%2d %2d:%02d:%02d\n", # $iNen, $iTuki, $iHi, $iHour, $iMin, $iSec; # print "CRC :$nCrc FLAG:$nUFlag OS :$nOStype\n"; # print "Attr:$sAttr Mode:$sMode\n"; #4.3 Get Next Information?iFindNext?j $nRes = $lhaFindNext->Call($nArc, $oPack); } #4.4 Close $lhaCloseArc->Call($nArc);
Results:
C:\User>perl lha.pl Ver: 126 Count: 15 Creating archive : c:/kabaya.lzh Frozen ==> 43% index.htm Frozen ==> 47% prm.htm Frozen ==> 14% unlharef.htm Frozen ==> 59% texp.htm Frozen ==> 29% perlmail.htm Frozen ==> 44% index.htm Frozen ==> 24% ppm.htm Frozen ==> 28% perlora.htm Frozen ==> 33% rcvmail.htm Extracting from archive : c:/kabaya.lzh mkdir c:/lhaext/Nifty Melted index.htm Melted prm.htm mkdir c:/lhaext/Nifty/v150 Melted unlharef.htm Melted texp.htm mkdir c:/lhaext/Nifty/PerlTips Melted perlmail.htm Melted index.htm Melted ppm.htm Melted perlora.htm Melted rcvmail.htm File:Nifty/index.htm SIZE:3029 -> 1314 (43.4) File:Nifty/prm.htm SIZE:3259 -> 1551 (47.6) File:Nifty/v150/unlharef.htm SIZE:61353 -> 8904 (14.5) File:Nifty/texp.htm SIZE:1538 -> 920 (59.8) File:Nifty/PerlTips/perlmail.htm SIZE:18760 -> 5574 (29.7) File:Nifty/PerlTips/index.htm SIZE:2331 -> 1040 (44.6) File:Nifty/PerlTips/ppm.htm SIZE:14902 -> 3589 (24.1) File:Nifty/PerlTips/perlora.htm SIZE:29187 -> 8168 (28) File:Nifty/PerlTips/rcvmail.htm SIZE:15563 -> 5151 (33.1) C:\User>