home *** CD-ROM | disk | FTP | other *** search
- <?xml version="1.0"?>
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/transitional.dtd">
- <html xmlns="http://www.w3.org/TR/xhtml1">
- <head>
- <title>perlwin32faq10 - Embedding and Extending</title>
- <link rev="made" href="mailto:bjepson@debian.ids.net" />
- <meta name="GENERATOR" charset="iso-8859-1" />
- <link rel="STYLESHEET" href="../win32prk.css" type="text/css"
- media="screen" />
- </head>
-
- <body bgcolor="#ffffff">
- <!-- beginning of leaf header-->
-
- <table width="100%">
- <tr>
- <td bgcolor="000000" width="70" height="31"><a href=
- "http://www.activestate.com/"><img src="ASbutton.gif" alt=
- "ActiveState Home Page" border="0" width="68" height=
- "30" /></a></td>
-
- <td width="10" bgcolor="#ffffff"> </td>
-
- <td valign="middle" bgcolor="#cc0066"><font face=
- "sans-serif" size="+1" color="#ff99cc">
- Win32 FAQ</font></td>
- </tr>
- </table>
- <!-- end of leaf content--><!-- INDEX BEGIN -->
-
- <ul>
- <li><a href="#NAME">NAME</a></li>
-
- <li>
- <a href="#DESCRIPTION">DESCRIPTION</a>
-
- <ul>
- <li><a href="#How_do_I_write_an_extension_for_">How do I
- write an extension for Perl for Win32?</a></li>
-
- <li><a href="#How_do_I_embed_the_Perl_interpre">How do I
- embed the Perl interpreter into my C/C++
- program?</a></li>
-
- <li><a href="#I_have_a_program_with_perl_embed">I have a
- program with perl embedded from the standard
- distribution.</a></li>
- </ul>
- </li>
-
- <li><a href="#AUTHOR_AND_COPYRIGHT">AUTHOR AND
- COPYRIGHT</a></li>
- </ul>
- <!-- INDEX END -->
- <hr />
- <br />
-
- <h1><a name="NAME">NAME</a></h1>
-
- <p>perlwin32faq10 - Embedding and Extending</p>
- <br />
- <hr />
-
- <h1><a name="DESCRIPTION">DESCRIPTION</a></h1>
-
- <p>Techniques for Embedding and Extending Perl for Win32</p>
- <br />
- <hr />
-
- <h2><a name="How_do_I_write_an_extension_for_">How do I write
- an extension for Perl for Win32?</a></h2>
-
- <p>Writing extensions in <font size="-1">C</font> or <font
- size="-1">C++</font> for Perl for Win32 is identical to writing
- them for standard Perl. Consult the perlxstut document for
- complete information and pointers to other sources of
- information.</p>
-
- <p>As a result of the oneperl effort, you now longer need to
- build Perl for Win32 from the source distribution to write or
- compile extensions. The Perl installation will detect your
- <font size="-1">C</font> compiler (currently, just Visual <font
- size="-1">C++),</font> and configure Perl to use it for
- compiling extensions.</p>
-
- <p>Note that writing extensions in <font size="-1">C</font> or
- <font size="-1">C++</font> is not easy. You need to have
- experience writing <font size="-1">C</font> programs for
- Windows platforms before you should even think about writing an
- extension.</p>
- <br />
- <hr />
-
- <h2><a name="How_do_I_embed_the_Perl_interpre">How do I embed
- the Perl interpreter into my C/C++ program?</a></h2>
-
- <p>As of build 500, this is quite easy. Perl for Win32 exposes
- Perl's internals through a <font size="-1">C++</font> object
- called <font size="-1">PERL_OBJECT.</font> Among other things,
- <font size="-1">PERL_OBJECT</font> simplifies the creation of
- multiple Perl interpreters within a single process.</p>
-
- <p>To embed Perl for Win32 in your own application, you must
- have the following:</p>
-
- <ul>
- <li>
- <p>Microsoft Visual <font size="-1">C++</font></p>
- </li>
-
- <li>
- <p> <font size="-1">A</font> binary release of Perl for
- Win32 (build 500 or later)</p>
- </li>
-
- <li>
- <p>The Perl for Win32 source code (the version of the
- source code must match the build of your binary version of
- Perl)</p>
- </li>
- </ul>
-
- <p>Before you can compile an application that embeds Perl for
- Win32, you must compile Perl from source. This does not mean
- that you must install Perl from source - the reason that you
- must compile Perl from source is that the compilation process
- creates the <em>DynaLoader.c</em> source code file, which is
- required if you want to use any extensions in your
- application.</p>
-
- <p>To compile Perl from source:</p>
-
- <ol>
- <li>
- <strong><a name="item_"></a></strong>
-
- <p>Change directory to the <em>win32</em> directory of your
- Perl source distribution and edit <em>Makefile</em> as
- necessary.</p>
- </li>
-
- <li>
-
-
- <p>Type <code>nmake</code>. This will compile all of
- Perl.</p>
- </li>
-
- <li>
-
-
- <p>Type <code>nmake test</code>. This ensures that Perl
- built correctly and passes all its tests.</p>
- </li>
-
- <li>
-
-
- <p>Perl is now compiled, and the <em>DynaLoader.c</em> file
- is created. If you did not install a binary release of
- Perl, you can issue the command <code>make install</code>,
- which will install Perl for you. This step is not necessary
- if you installed a binary release of Perl.</p>
- </li>
- </ol>
-
- <p>Once you have compiled Perl from source, you have a source
- tree that can be used to build an embedded version of Perl.
- Here is a simple program that includes an embedded Perl
- interpreter. It is actually quite a bit like <em>perl.exe</em>.
- You can use all the command-line switches that are supported by
- perl, and you can also include the name of a script to execute.
- If you supply no switches, it will read in a Perl program from
- standard input, and executes the program when end-of-file is
- encountered. Save this file as <em>MyPerl.cpp</em> on your
- computer (remember to outdent the source code):</p>
- <br />
- <pre>
- /*
-
- 1) include perlhost.h. This header defines all the
- OS Interfaces that are used by the PERL_OBJECT.
- 2) define the host data structure 'CPerlHost'
- 3) call the CPerlHost member function PerlCreate,
- which calls perl_alloc and perl_construct
- 4) call the CPerlHost member function PerlParse
- 5) call the CPerlHost member function PerlRun
- 6) when done, call the CPerlHost member function PerlDestroy,
- which calls perl_destruct and perl_free
-
- Including XSUB.h brings in the files that have macros to redefine
- the perl_* functions, to work with PERL_OBJECT. Note that these
- macros may cause problems when there are name collisions. A common
- problem is having a local variable that has the same name as a Perl
- function. To track down these name collisions compile using '/P'
- option with VC++ so that you can see what the preprocessor has done.
-
- */
- #include <EXTERN.h>
- #include <perl.h>
- #define NO_XSLOCKS
-
- // Bring in the macros that redefine perl_* functions to work with
- // PERL_OBJECT.
- //
- #include <XSUB.h>
-
- /* for Win32 */
- #include "win32iop.h"
- #include <fcntl.h>
- #include <perlhost.h>
- #include <stdio.h>
-
- // DynaLoader stuff.
- //
- char *staticlinkmodules[] = {
- "DynaLoader",
- NULL,
- };
-
- // More DynaLoader stuff.
- //
- EXTERN_C void boot_DynaLoader _((CV* cv _CPERLarg));
-
- static void
- xs_init(CPERLarg)
- {
- char *file = __FILE__;
- dXSUB_SYS;
- newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
- }
-
- CPerlObj *pPerl; // The Perl object used by the host.
-
- int main (int argc, char **argv, char **env)
- {
- CPerlHost host; // The Perl host
- host.PerlCreate(); // Create an instance of the Perl Interpreter
-
- printf("Welcome to my very own Perl!\n\n");
-
- // Read arguments from the command line. If no script is named on the
- // command-line, and nothing is specified for -e, the interpreter will
- // read commands from standard input (just like Perl!).
- //
- host.PerlParse(xs_init, argc, argv, NULL);
-
- host.PerlRun(); // Run the interpreter.
- host.PerlDestroy(); // Destroy the interpreter.
- return 0;
- }
- </pre>
-
- <p>To compile this program, you must use the following <em>
- Makefile</em>. Be sure to update <code>LIBDIR</code> to point
- to the <em>CORE</em> subdirectory of your Perl binary
- installation, and update <code>SRCDIR</code> to point to the
- <em>src</em> directory of the Perl source code that you
- compiled earlier. Save this file as <em>Makefile</em> (remember
- to outdent the contents):</p>
- <br />
- <pre>
- LIBDIR = C:\Perl\5.00500\lib\MSWin32-x86\CORE
- SRCDIR = C:\5.00500\src
-
- LIBS = oldnames.lib kernel32.lib user32.lib winspool.lib advapi32.lib \
- shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib \
- wsock32.lib version.lib PerlCRT.lib $(LIBDIR)\PerlCore.lib
- </pre>
- <br />
- <pre>
- CCFLAGS = -c -I$(LIBDIR) -Gf -W3 -DWIN32 -D_CONSOLE -DPERL_CORE \
- -O2 -MD -DNDEBUG -TP -GX -DPERL_OBJECT -UPERLDLL
- CCDYNA = $(CCFLAGS) -I$(SRCDIR)\ext\DynaLoader
-
- all:
- cl.exe $(CCFLAGS) -Fo.\MyPerl.obj MyPerl.cpp
- cl.exe $(CCFLAGS) -Fo.\win32.obj $(SRCDIR)\win32\win32.c
- cl.exe $(CCFLAGS) -Fo.\win32sck.obj $(SRCDIR)\win32\win32sck.c
- cl.exe $(CCFLAGS) -Fo.\DynaLoader.obj \
- $(SRCDIR)\ext\DynaLoader\DynaLoader.c
- link.exe -nologo -nodefaultlib -release -machine:x86 $(LIBS) \
- -subsystem:console MyPerl.obj win32.obj win32sck.obj \
- DynaLoader.obj setargv.obj
- </pre>
-
- <p>Make sure that <em>PerlCRT.lib</em> has been installed
- properly. For more information, see <a href=
- "#How_do_I_write_an_extension_for_">How do I write an extension
- for Perl for Win32?</a>.</p>
-
- <p>You can then compile <em>MyPerl.cpp</em> by typing <code>
- nmake</code> at the command line (make sure that both <em>
- MyPerl.cpp</em> and <em>Makefile</em> are in your current
- working directory). This will produce the file <em>
- MyPerl.exe</em>, which you can run at the command line as
- though it were <em>perl.exe</em>:</p>
- <br />
- <pre>
- C:\MyPerl>myperl -e "print qq[Hello, World\n];"
- Welcome to my very own Perl!
-
- Hello, World
- </pre>
-
- <p>or:</p>
- <br />
- <pre>
- C:\MyPerl>myperl
- Welcome to my very own Perl!
-
- print "Hello, world\n";
- ^Z
- Hello, world
- </pre>
-
- <p>If you want to use modules and extensions from your local
- Perl installation, you'll need to do one of two things. The
- simplest thing you can do is copy your executable to the same
- location as perl.exe.</p>
-
- <p>If this is not an option, you need to tell your program
- where to find things. This can be accomplished by setting the
- <code>PERL5LIB</code> environment variable with something
- like:</p>
- <br />
- <pre>
- set PERL5LIB=C:\Perl\5.00500\lib;C:\Perl\site\5.00500\lib;C:\Perl\site\lib
- </pre>
-
- <p>Then you can use modules and extensions from your local Perl
- installation:</p>
- <br />
- <pre>
- C:\MyPerl>MyPerl -MWin32::OLE -e "print $Win32::OLE::VERSION;"
- Welcome to my very own Perl!
-
- 0.0807
- </pre>
-
- <p>The following example is based on the PerlPower example from
- Doug MacEachern and Jon Orwant's perlembed document (this is
- part of Perl, and you should have a copy included with Perl for
- Win32). You should save the following program as <em>
- PerlPower.cpp</em>:</p>
- <br />
- <pre>
- /*
- To show how to embed Perl with PERL_OBJECT defined, we will show the
- changes needed for the PerlPower sample that is in perlembed.pod.
-
- 1) include perlhost.h. This header defines all the
- OS Interfaces that are used by the PERL_OBJECT.
- 2) define the host data structure 'CPerlHost'
- 3) call the CPerlHost member function PerlCreate,
- which calls perl_alloc and perl_construct
- 4) call the CPerlHost member function PerlParse
- 5) call the CPerlHost member function PerlRun
- 6) call any of the perl_call_* functions
- 7) when done, call the CPerlHost member function PerlDestroy,
- which calls perl_destruct and perl_free
-
- Including XSUB.h brings in the files that have macros to redefine the
- perl_* functions, to work with PERL_OBJECT. Note that these macros may
- cause problems when there are name collisions. A common problem is
- having a local variable that has the same name as a Perl function. To
- track down these name collisions compile using '/P' option with VC++ so
- that you can see what the preprocessor has done.
-
- */
-
- #include <EXTERN.h>
- #include <perl.h>
-
- #define NO_XSLOCKS
-
- // Bring in the macros that redefine perl_* functions to work with
- // PERL_OBJECT.
- //
- #include <XSUB.h>
-
- /* for Win32 */
- #include "win32iop.h"
- #include <fcntl.h>
- #include <perlhost.h>
-
- // DynaLoader stuff.
- //
- char *staticlinkmodules[] = {
- "DynaLoader",
- NULL,
- };
-
- // More DynaLoader stuff.
- //
- EXTERN_C void boot_DynaLoader _((CV* cv _CPERLarg));
- static void
- xs_init(CPERLarg)
- {
- char *file = __FILE__;
- dXSUB_SYS;
- newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
- }
-
- CPerlObj *pPerl;
-
- static void
- PerlPower(int a, int b)
- {
- dSP; /* initialize stack pointer */
- ENTER; /* everything created after here */
- SAVETMPS; /* ...is a temporary variable. */
- PUSHMARK(SP); /* remember the stack pointer */
- XPUSHs(sv_2mortal(newSViv(a))); /* push the base onto the stack */
- XPUSHs(sv_2mortal(newSViv(b))); /* push the exponent onto stack */
- PUTBACK; /* make local stack pointer global */
- perl_call_pv("expo", G_SCALAR); /* call the function */
- SPAGAIN; /* refresh stack pointer */
- /* pop the return value from stack */
-
- printf ("%d to the %dth power is %d.\n", a, b, POPi);
- PUTBACK;
- FREETMPS; /* free that return value */
- LEAVE; /* ...and the XPUSHed "mortal" args.*/
- }
-
- int main (int argc, char **argv, char **env)
- {
- CPerlHost host;
-
- host.PerlCreate();
-
- // Don't use argv or argc for embedding. Instead, we'll pretend that
- // we gave it the arguments "-e 0".
- //
- char *embedding[] = { "", "-e", "0" };
- host.PerlParse(xs_init, 3, embedding, NULL);
-
- // Define the expo() function.
- //
- perl_eval_pv("sub expo { my($a, $b) = @_; return $a ** $b; }", TRUE);
-
- host.PerlRun();
-
- PerlPower(3, 4); /*** Compute 3 ** 4 ***/
-
- host.PerlDestroy();
- return 0;
- }
- </pre>
-
- <p>The following <em>Makefile</em> can be used to compile <em>
- PerlPower.cpp</em>:</p>
- <br />
- <pre>
- LIBDIR = C:\Perl\5.00468\lib\MSWin32-x86\CORE
- SRCDIR = C:\betab9\src
-
- LIBS = oldnames.lib kernel32.lib user32.lib winspool.lib advapi32.lib \
- shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib \
- wsock32.lib version.lib PerlCRT.lib $(LIBDIR)\PerlCore.lib
-
- CCFLAGS = -c -I$(LIBDIR) -Gf -W3 -DWIN32 -D_CONSOLE -DPERL_CORE \
- -O2 -MD -DNDEBUG -TP -GX -DPERL_OBJECT -UPERLDLL
- CCDYNA = $(CCFLAGS) -I$(SRCDIR)\ext\DynaLoader
-
- all:
- cl.exe $(CCFLAGS) -Fo.\PerlPower.obj PerlPower.cpp
- cl.exe $(CCFLAGS) -Fo.\win32.obj $(SRCDIR)\win32\win32.c
- cl.exe $(CCFLAGS) -Fo.\win32sck.obj $(SRCDIR)\win32\win32sck.c
- cl.exe $(CCFLAGS) -Fo.\DynaLoader.obj \
- $(SRCDIR)\ext\DynaLoader\DynaLoader.c
- link.exe -nologo -nodefaultlib -release -machine:x86 $(LIBS) \
- -subsystem:console PerlPower.obj win32.obj win32sck.obj \
- DynaLoader.obj setargv.obj
- </pre>
-
- <p>As with the <em>MyPerl.cpp</em> example <em>Makefile</em>,
- be sure that <code>SRCDIR</code> and <code>LIBDIR</code> point
- to the correct directories. You can compile <em>
- PerlPower.cpp</em> by typing <code>nmake</code> at the command
- line (make sure that both <em>PerlPower.cpp</em> and <em>
- Makefile</em> are in your current working directory). This will
- produce the file <em>PerlPower.exe</em>, which you can run at
- the command line:</p>
- <br />
- <pre>
- C:\PerlPower>PerlPower
- 3 to the 4th power is 81.
- </pre>
-
- <p>You should definitely read the perlembed document in its
- entirety to get an overview of the issues involved with
- embedding Perl. Then, you can use the <em>MyPerl.cpp</em> and
- <em>PerlPower.cpp</em> as guides for embedding Perl for
- Win32.</p>
- <br />
- <hr />
-
- <h2><a name="I_have_a_program_with_perl_embed">I have a program
- with perl embedded from the standard distribution. Why won't it
- compile with Perl for Win32?</a></h2>
-
- <p>Perl for Win32 exposes the Perl interpreter in a slightly
- different fashion than standard Perl. For information on how to
- embed using Perl for Win32, see <a href=
- "#How_do_I_embed_the_Perl_interpre">How do I embed the Perl
- interpreter into my C/C++ program?</a>.</p>
- <br />
- <hr />
-
- <h1><a name="AUTHOR_AND_COPYRIGHT">AUTHOR AND
- COPYRIGHT</a></h1>
-
- <p>This <font size="-1">FAQ</font> was originally assembled and
- maintained by Evangelo Prodromou. <a href=
- "mailto:evangelo@endcontsw.com">evangelo@endcontsw.com.</a> It
- has been revised and updated by Brian Jepson of O'Reilly and
- Associates, and David Grove and David Dmytryshyn of
- ActiveState.</p>
-
- <p>This <font size="-1">FAQ</font> is in the public domain. If
- you use it, however, please ensure that you give credit to the
- original authors.</p>
-
- <p><!-- beginning of leaf footer--></p>
-
- <table width="100%">
- <tr>
- <td bgcolor="000000" width="70" height="31"><a href=
- "http://www.activestate.com/"><img src="ASbutton.gif" alt=
- "ActiveState Home Page" border="0" width="68" height=
- "30" /></a></td>
-
- <td width="10"> </td>
-
- <td valign="middle" bgcolor="#cc0066"><font face=
- "sans-serif" size="+1" color="#ff99cc">
- Win32 FAQ</font></td>
- </tr>
- </table>
- <!-- end of leaf footer-->
- </body>
- </html>
-
-