home *** CD-ROM | disk | FTP | other *** search
/ Chip 2000 May / Chip_2000-05_cd1.bin / zkuste / Perl / ActivePerl-5.6.0.613.msi / 䆊䌷䈹䈙䏵-䞅䞆䞀㡆䞃䄦䠥 / _4b4ecaf6c70a9b0d2ef1ea0d577c27ff < prev    next >
Text File  |  2000-03-23  |  13KB  |  295 lines

  1.  
  2. <HTML>
  3. <HEAD>
  4. <TITLE>Win32::API - Implementation of arbitrary Win32 APIs.</TITLE>
  5. <LINK REL="stylesheet" HREF="../../../Active.css" TYPE="text/css">
  6. <LINK REV="made" HREF="mailto:">
  7. </HEAD>
  8.  
  9. <BODY>
  10. <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
  11. <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
  12. <STRONG><P CLASS=block> Win32::API - Implementation of arbitrary Win32 APIs.</P></STRONG>
  13. </TD></TR>
  14. </TABLE>
  15.  
  16. <A NAME="__index__"></A>
  17. <!-- INDEX BEGIN -->
  18.  
  19. <UL>
  20.  
  21.     <LI><A HREF="#name">NAME</A></LI><LI><A HREF="#supportedplatforms">SUPPORTED PLATFORMS</A></LI>
  22.  
  23.     <LI><A HREF="#synopsis">SYNOPSIS</A></LI>
  24.     <LI><A HREF="#abstract">ABSTRACT</A></LI>
  25.     <LI><A HREF="#credits">CREDITS</A></LI>
  26.     <LI><A HREF="#installation">INSTALLATION</A></LI>
  27.     <LI><A HREF="#description">DESCRIPTION</A></LI>
  28.     <UL>
  29.  
  30.         <LI><A HREF="#importing a function">IMPORTING A FUNCTION</A></LI>
  31.         <LI><A HREF="#calling an imported function">CALLING AN IMPORTED FUNCTION</A></LI>
  32.     </UL>
  33.  
  34.     <LI><A HREF="#author">AUTHOR</A></LI>
  35. </UL>
  36. <!-- INDEX END -->
  37.  
  38. <HR>
  39. <P>
  40. <H1><A NAME="name">NAME</A></H1>
  41. <P>Win32::API - Implementation of arbitrary Win32 APIs.</P>
  42. <P>
  43. <HR>
  44. <H1><A NAME="supportedplatforms">SUPPORTED PLATFORMS</A></H1>
  45. <UL>
  46. <LI>Windows</LI>
  47. </UL>
  48. <HR>
  49. <H1><A NAME="synopsis">SYNOPSIS</A></H1>
  50. <PRE>
  51.   use Win32::API;
  52.   $function = new Win32::API($library, 
  53.                              $functionname, 
  54.                              \@argumenttypes, 
  55.                              $returntype);
  56.   $return = $function->Call(@arguments);</PRE>
  57. <P>
  58. <HR>
  59. <H1><A NAME="abstract">ABSTRACT</A></H1>
  60. <P>With this module you can import and call arbitrary functions
  61. from Win32's Dynamic Link Libraries (DLL).</P>
  62. <P>The current version of Win32::API is available at:</P>
  63. <PRE>
  64.   <A HREF="http://www.divinf.it/dada/perl/api/">http://www.divinf.it/dada/perl/api/</A></PRE>
  65. <P>It is also available on your nearest CPAN mirror 
  66. (but allow a few days for worldwide spreading of the latest version) 
  67. reachable at:</P>
  68. <PRE>
  69.   <A HREF="http://www.perl.com/CPAN/authors/Aldo_Calpini/">http://www.perl.com/CPAN/authors/Aldo_Calpini/</A></PRE>
  70. <P>
  71. <HR>
  72. <H1><A NAME="credits">CREDITS</A></H1>
  73. <P>All the credits go to Andrea Frosini ( <EM><A HREF="mailto:frosini@programmers.net">frosini@programmers.net</A></EM> ),
  74. for his bits of magic - eg. the assembler trick that make this thing work.
  75. A big thank you also to Gurusamy Sarathy ( <EM><A HREF="mailto:gsar@engin.umich.edu">gsar@engin.umich.edu</A></EM> ) for his
  76. help in XS development <CODE>:)</CODE></P>
  77. <P>
  78. <HR>
  79. <H1><A NAME="installation">INSTALLATION</A></H1>
  80. <P>This module comes with pre-built binaries for:</P>
  81. <DL>
  82. <DT><STRONG><A NAME="item_higher">The Perl for Win32 port by ActiveWare: 
  83. Build 300 or higher (EXCEPT 304!)</A></STRONG><BR>
  84. <DD>
  85. <DT><STRONG><A NAME="item_The_core_Perl_5%2E004_distribution%3A_Built_on_the">The core Perl 5.004 distribution: 
  86. Built on the Win32 platform, of course...</A></STRONG><BR>
  87. <DD>
  88. </DL>
  89. <P>To install the package, just change to the directory in which you 
  90. uncompressed it and type the following:</P>
  91. <PRE>
  92.     install</PRE>
  93. <P>This will take care of copying the right files to the right 
  94. places for use by all your perl scripts.</P>
  95. <P>If you're running the core Perl 5.004 distribution, you can
  96. also build the extension by yourself with the following procedure:</P>
  97. <PRE>
  98.     perl Makefile.PL
  99.     nmake
  100.     nmake install</PRE>
  101. <P>If you are instead running the ActiveWare Perl for Win32 port, the 
  102. sources to rebuild the extension are in the <EM>ActiveWare/source</EM> directory.
  103. You should put those files in the following directory:</P>
  104. <PRE>
  105.     (perl-src)\ext\Win32\API</PRE>
  106. <P>Where <CODE>(perl-src)</CODE> is the location of your Perl-Win32 source files.</P>
  107. <P>
  108. <HR>
  109. <H1><A NAME="description">DESCRIPTION</A></H1>
  110. <P>To use this module put the following line at the beginning of your script:</P>
  111. <PRE>
  112.     use Win32::API;</PRE>
  113. <P>You can now use the <CODE>new()</CODE> function of the Win32::API module to create a
  114. new API object (see <A HREF="#importing a function">IMPORTING A FUNCTION</A>) and then invoke the 
  115. <CODE>Call()</CODE> method on this object to perform a call to the imported API
  116. (see <A HREF="#calling an imported function">CALLING AN IMPORTED FUNCTION</A>).</P>
  117. <P>
  118. <H2><A NAME="importing a function">IMPORTING A FUNCTION</A></H2>
  119. <P>You can import a function from a Dynamic Link Library (DLL) file with
  120. the <CODE>new()</CODE> function. This will create a Perl object that contains the
  121. reference to that function, which you can later Call().
  122. You need to pass 4 parameters:</P>
  123. <OL>
  124. <LI><STRONG><A NAME="item_The_name_of_the_library_from_which_you_want_to_imp">The name of the library from which you want to import the function.</A></STRONG><BR>
  125.  
  126. <LI><STRONG><A NAME="item_function">The name of the function (as exported by the library).</A></STRONG><BR>
  127.  
  128. <LI><STRONG><A NAME="item_The_number_and_types_of_the_arguments_the_function">The number and types of the arguments the function expects as input.</A></STRONG><BR>
  129.  
  130. <LI><STRONG><A NAME="item_The_type_of_the_value_returned_by_the_function%2E">The type of the value returned by the function.</A></STRONG><BR>
  131.  
  132. </OL>
  133. <P>To explain better their meaning, let's make an example:
  134. I want to import and call the Win32 API <CODE>GetTempPath()</CODE>.
  135. This function is defined in C as:</P>
  136. <PRE>
  137.     DWORD WINAPI GetTempPathA( DWORD nBufferLength, LPSTR lpBuffer );</PRE>
  138. <P>This is documented in the <STRONG>Win32 SDK Reference</STRONG>; look
  139. for it on the Microsoft's WWW site. If you own Visual C++,
  140. searching in the include files is much faster.</P>
  141. <P><STRONG>1.</STRONG></P>
  142. <P>The first parameter is the name of the library file that 
  143. exports this function; our function resides in the <EM>KERNEL32.DLL</EM>
  144. system file.
  145. When specifying this name as parameter, the <EM>.dll</EM> extension
  146. is implicit, and if no path is given, the file is searched through
  147. the Windows directories. So I don't have to write 
  148. <EM>C:\windows\system\kernel32.dll</EM>; only <EM>kernel32</EM> is enough:</P>
  149. <PRE>
  150.     $GetTempPath = new Win32::API("kernel32", ...</PRE>
  151. <P><STRONG>2.</STRONG></P>
  152. <P>Now for the second parameter: the name of the function.
  153. It must be written exactly as it is exported 
  154. by the library (case is significant here). 
  155. If you are using Windows 95 or NT 4.0, you can use the <STRONG>Quick View</STRONG> 
  156. command on the DLL file to see the function it exports. 
  157. Note that many Win32 APIs are exported twice, with the addition of
  158. a final <STRONG>A</STRONG> or <STRONG>W</STRONG> to their name, for - respectively - the ASCII 
  159. and the Unicode version.
  160. Win32::API, when a function name is not found, will actually append
  161. an <STRONG>A</STRONG> to the name and try again. If you are using Unicode, you
  162. will just need to rebuild the module; then Win32::API will 
  163. try with the <STRONG>W</STRONG>.
  164. So my function name will be:</P>
  165. <PRE>
  166.     $GetTempPath = new Win32::API("kernel32", "GetTempPath", ...</PRE>
  167. <P>Note that <CODE>GetTempPath</CODE> is really loaded as <CODE>GetTempPathA</CODE>.</P>
  168. <P><STRONG>3.</STRONG></P>
  169. <P>The third parameter, the input parameter list, specifies how many 
  170. arguments the function wants, and their types. It <STRONG>MUST</STRONG> be passed 
  171. as a list reference. The following forms are valid:</P>
  172. <PRE>
  173.     [a, b, c, d]
  174.     \@LIST</PRE>
  175. <P>But those are not:</P>
  176. <PRE>
  177.     (a, b, c, d)
  178.     @LIST</PRE>
  179. <P>The number of elements in the list specifies the number of parameters,
  180. and each element in the list specifies the type of an argument; allowed
  181. types are:</P>
  182. <DL>
  183. <DT><STRONG><A NAME="item_I%3A_value_is_an_integer"><CODE>I</CODE>: 
  184. value is an integer</A></STRONG><BR>
  185. <DD>
  186. <DT><STRONG><A NAME="item_number"><CODE>N</CODE>: 
  187. value is a number (long)</A></STRONG><BR>
  188. <DD>
  189. <DT><STRONG><A NAME="item_pointer"><CODE>P</CODE>: 
  190. value is a pointer (to a string, structure, etc...)</A></STRONG><BR>
  191. <DD>
  192. </DL>
  193. <P>Our function needs two parameters: a number (<CODE>DWORD</CODE>) and a pointer to a 
  194. string (<CODE>LPSTR</CODE>):</P>
  195. <PRE>
  196.     $GetTempPath = new Win32::API("kernel32", "GetTempPath", [N, P], ...</PRE>
  197. <P><STRONG>4.</STRONG></P>
  198. <P>The fourth and final parameter is the type of the value returned by the 
  199. function. It can be one of the types seen above, plus another type named <STRONG>V</STRONG> 
  200. (that stands for <A HREF="../../../lib/Pod/perlguts.html#item_void"><CODE>void</CODE></A>) to indicate that the function doesn't return a value.
  201. In our example the value returned by <CODE>GetTempPath()</CODE> is a <CODE>DWORD</CODE>, so 
  202. our return type will be <STRONG>N</STRONG>:</P>
  203. <PRE>
  204.     $GetTempPath = new Win32::API("kernel32", "GetTempPath", [N, P], N);</PRE>
  205. <P>Now the line is complete, and the API <CODE>GetTempPath()</CODE> is available for use 
  206. in Perl. Before you can call it, you should test that $GetTempPath is 
  207. <A HREF="../../../lib/Pod/perlfunc.html#item_defined"><CODE>defined</CODE></A>, otherwise either the function or the library has not been found.</P>
  208. <P>
  209. <H2><A NAME="calling an imported function">CALLING AN IMPORTED FUNCTION</A></H2>
  210. <P>To effectively make a call to an imported function you must use the
  211. <CODE>Call()</CODE> method on the Win32::API object you created.
  212. To continue with the example from the previous paragraph, I can
  213. call the <CODE>GetTempPath()</CODE> API via the method:</P>
  214. <PRE>
  215.     $GetTempPath->Call(...</PRE>
  216. <P>Of course I have to pass the parameters as defined in the import phase.
  217. In particular, if the number of parameters does not match (in the example,
  218. if I call <CODE>GetTempPath()</CODE> with more or less than two parameters), 
  219. Perl will <CODE>croak</CODE> an error message and <A HREF="../../../lib/Pod/perlfunc.html#item_die"><CODE>die</CODE></A>.</P>
  220. <P>So I need two parameters here: the first is the length of the buffer
  221. that will hold the returned temporary path, the second is the buffer
  222. itself.
  223. For numerical parameters you can use either a constant expression
  224. or a variable, while <STRONG>for pointers you must use a variable name</STRONG> (no 
  225. reference, just a plain variable name).
  226. Also note that <STRONG>memory must be allocated before calling the function</STRONG>.
  227. For example, if I want to pass a buffer of 80 characters to GetTempPath(),
  228. I have to initialize it before with:</P>
  229. <PRE>
  230.     $lpBuffer = " " x 80;</PRE>
  231. <P>This allocates a string of 80 characters. If you don't do so, you'll
  232. probably get '<CODE>Runtime exception</CODE>' errors, and generally nothing will 
  233. work. My call should therefore include:</P>
  234. <PRE>
  235.     $lpBuffer = " " x 80;
  236.     $GetTempPath->Call(80, $lpBuffer);</PRE>
  237. <P>And the result will be stored in the $lpBuffer variable.
  238. Note, however, that Perl does not trim the variable, so $lpBuffer
  239. will contain 80 characters in return; the exceeding characters
  240. will be spaces, since I initialized the variable with <CODE>" " x 80</CODE>.
  241. In this case I'm lucky enough, because the value returned by 
  242. the <CODE>GetTempPath()</CODE> function is the length of the string, so to get
  243. the actual temporary path I write:</P>
  244. <PRE>
  245.     $lpBuffer = " " x 80;
  246.     $return = $GetTempPath->Call(80, $lpBuffer);
  247.     $TempPath = substr($lpBuffer, 0, $return);</PRE>
  248. <P>If you don't know the length of the string, you can usually
  249. cut it at the \0 (ASCII zero) character, which is the string
  250. delimiter in C:</P>
  251. <PRE>
  252.     $TempPath = ((split(/\0/, $lpBuffer))[0];
  253. </PRE>
  254. <PRE>
  255.  
  256.     # or</PRE>
  257. <PRE>
  258.  
  259.     $lpBuffer =~ s/\0.*$//;
  260.     $TempPath = $lpBuffer;</PRE>
  261. <P>Another note: to pass a pointer to a structure in C, you'll have
  262. to <A HREF="../../../lib/Pod/perlfunc.html#item_pack"><CODE>pack()</CODE></A> the required elements in a variable. And of course, to 
  263. access the values stored in a structure, <A HREF="../../../lib/Pod/perlfunc.html#item_unpack"><CODE>unpack()</CODE></A> it as required.
  264. An example of how it works: we have the <CODE>POINT</CODE> structure 
  265. defined in C as:</P>
  266. <PRE>
  267.     typedef struct {
  268.         LONG  x;
  269.         LONG  y;
  270.     } POINT;</PRE>
  271. <P>Thus, to call a function that uses a <CODE>POINT</CODE> structure you
  272. will need the following lines:</P>
  273. <PRE>
  274.     $GetCursorPos = new Win32::API("user32", "GetCursorPos", [P], V);
  275. </PRE>
  276. <PRE>
  277.  
  278.     $lpPoint = pack("LL", 0, 0); # store two LONGs
  279.     $GetCursorPos->Call($lpPoint);
  280.     ($x, $y) = unpack("LL", $lpPoint); # get the actual values</PRE>
  281. <P>The rest is left as an exercise to the reader...</P>
  282. <P>
  283. <HR>
  284. <H1><A NAME="author">AUTHOR</A></H1>
  285. <P>Aldo Calpini ( <EM><A HREF="mailto:dada@divinf.it">dada@divinf.it</A></EM> ).</P>
  286. <TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0 WIDTH=100%>
  287. <TR><TD CLASS=block VALIGN=MIDDLE WIDTH=100% BGCOLOR="#cccccc">
  288. <STRONG><P CLASS=block> Win32::API - Implementation of arbitrary Win32 APIs.</P></STRONG>
  289. </TD></TR>
  290. </TABLE>
  291.  
  292. </BODY>
  293.  
  294. </HTML>
  295.