home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2000 May
/
Chip_2000-05_cd1.bin
/
zkuste
/
Perl
/
ActivePerl-5.6.0.613.msi
/
䆊䌷䈹䈙䏵-䞅䞆䞀㡆䞃䄦䠥
/
_defa3e53d0c7c88bb443b222870c666c
< prev
next >
Wrap
Text File
|
2000-03-22
|
18KB
|
412 lines
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<HEAD>
<TITLE>ActivePerl faq10 - Embedding and Extending</TITLE>
<LINK rev="made" href="mailto:support@ActiveState.com">
<META name="GENERATOR" charset="iso-8859-1" content="Microsoft FrontPage 4.0">
<META name="ProgId" content="FrontPage.Editor.Document">
<LINK rel="STYLESHEET" href="../../Active.css" type="text/css" media="screen">
</HEAD>
<BODY bgcolor="#ffffff">
<!-- beginning of leaf header-->
<TABLE border="0" cellpadding="0" cellspacing="0" width="100%">
<TR>
<TD class="block" valign="MIDDLE" width="100%" bgcolor="#cccccc"><FONT size="+1"><STRONG>
<P class="block"> ActivePerl FAQ</P>
</STRONG></FONT></TD>
</TR>
</TABLE>
<BR>
<!-- 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 ActivePerl?</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>
<H1><A name="NAME">NAME</A></H1>
<P>perlwin32faq10 - Embedding and Extending</P>
<HR>
<H1><A name="DESCRIPTION">DESCRIPTION</A></H1>
<P>Techniques for Embedding and Extending ActivePerl</P>
<HR>
<H2><A name="How_do_I_write_an_extension_for_">How do I write an extension for ActivePerl?</A></H2>
<P>Writing extensions in <FONT size="-1">C</FONT> or <FONT size="-1">C++</FONT> for ActivePerl 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 ActivePerl 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>
<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. ActivePerl 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 ActivePerl 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 ActivePerl (build 500 or later)</P>
</LI>
<LI>
<P>The ActivePerl 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 ActivePerl, 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>
<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>
<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>
<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 ActivePerl?</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>
<PRE>
C:\MyPerl>myperl -e "print qq[Hello, World\n];"
Welcome to my very own Perl!
Hello, World
</PRE>
<P>or:</P>
<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>
<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>
<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 ActivePerl). You
should save the following program as <EM>PerlPower.cpp</EM>:</P>
<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>
<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>
<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 ActivePerl.</P>
<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 ActivePerl?</A></H2>
<P>ActivePerl exposes the Perl interpreter in a slightly different fashion than standard Perl. For
information on how to embed using ActivePerl, see <A href="#How_do_I_embed_the_Perl_interpre">How do
I embed the Perl interpreter into my C/C++ program?</A>.</P>
<HR>
<H1><A name="AUTHOR_AND_COPYRIGHT">AUTHOR AND COPYRIGHT</A></H1>
<P> </P>
<P>This <FONT size="-1">FAQ</FONT> was originally assembled and maintained by Evangelo Prodromou. It
has been revised and updated by Brian Jepson of O'Reilly & Associates, David Grove, David
Dmytryshyn, and David Sparks 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. <!-- beginning of leaf footer-->
</P>
<TABLE border="0" cellpadding="0" cellspacing="0" width="100%">
<TR>
<TD class="block" valign="MIDDLE" width="100%" bgcolor="#cccccc"><FONT size="+1"><STRONG>
<P class="block"> ActivePerl FAQ</P>
</STRONG></FONT></TD>
</TR>
</TABLE>
<!-- end of leaf footer-->
</BODY>
</HTML>