// PerlWrap.h : header file
//
// Simple wrapper based on Perl guts and embed pages.
//
// 7/30/2003 -- converted to use Perl58, and Perl headers moved
// to PerlWrap.cpp to avoid polluting namespace
// (see PXPerl at www.codeproject.com for another Perl wrapper)
//
// 2/21/2012 -- converted to Perl 5.14
#if !defined(AFX_PERLWRAP_H__812B9B44_72D2_48FA_944D_76D7D4AA6E1D__INCLUDED_)
#define AFX_PERLWRAP_H__812B9B44_72D2_48FA_944D_76D7D4AA6E1D__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif
// Adjust this to point to the proper .lib file for Perl on your machine
// Remember to package Perl58.dll along with your project when you install
// onto other machines!
#if !defined(NOIMPLINK) && (defined(_MSC_VER) || defined(__BORLANDC__))
//# pragma comment(lib,"C:/Perl/lib/CORE/Perl58.lib")
//# pragma comment(lib,"C:/Perl/lib/CORE/Perl510.lib")
# pragma comment(lib,"C:/Perl/lib/CORE/perl514.lib")
#endif
////////////////////////////////////////////////////////////////////////////////
// To get the Perl CORE files you need to add an include path:
//
// In Project->Settings...
// Settings for: All Configurations
// C/C++ tab
// Category: Preprocessor
// Additional include directories:
// C:\Perl\lib\CORE
//
// If the pragma 'comment' above doesn't work (or offends you) then do
// the following instead:
//
// Add library path: c:/Perl/lib/CORE
// Add library file: Perl514.lib (or Perl.lib if you have it renamed)
//
// See the perlembed web page for details. But be aware that the page is
// not completely up to date. For instance, the genmake stuff just doesn't
// seem to work (at least not under cygwin).
//
/////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////
// This class is a very basic wrapper for the Perl .dll (Perl58.dll) running
// as a thread within the current process. Support for multiple instances of
// Perl (in different threads) is provided. Each instantiation of a CPerlWrap
// gets its own instance of Perl running in its own thread.
//
// One major limitation is that if you are using modules (other than Perl
// pragmas like 'use warning;' or 'use int;') then the machine must have a full
// Perl installation. If the modules are pure Perl code (such as CGI) then you
// can work around this by including a copy of the subdirectory needed by the
// module. Perl expects a particular structure and modifying that is beyond me.
//
// However, if you are just using straight Perl (regex, lists, hashes, etc.) then
// all you need at runtime is Perl58.dll. You still need the Perl installation
// to compile the program, particularly the CORE headers.
//////////////////////////////////////////////////////////////////////////////////
class CPerlWrap
{
// Construction
public:
CPerlWrap();
// Attributes
private:
// Use void* to keep down the namespace pollution
//PerlInterpreter *my_perl; // current instance of Perl
//SV *last_eval; // return VALUE from last eval() (not success/fail)
void *last_eval; // return VALUE from last eval() (not success/fail)
void *my_perl; // current instance of Perl
CString eval_error; // error message from last eval (found in $@)
BOOL failOnWarning; // set if any warnings constitute a failure of doScript()
BOOL clearWarningsOnScript; // set if warnings are cleared before executing a script
// Operations
// I discovered by accident that the comment on the same line as the method declaration
// is displayed by Visual Studio in the class members drop-down list. That is, to use
// Intellisense in Visual Studio, this is how it is done.
//
// For instance, if I have an instance of CPerlWrap called perlInst and I type in
// 'perlInst.' then a drop-down list of all available members is displayed. As you
// continue to type (perlInst.getA) the selection has terse recognition and will scroll
// down to getArrayVal and the comment 'get array (@varName) as a CStringArray' will be
// displayed as a hint. Well, that hint is the comment on the declaration line. So if
// the comments below seem pendantic, it is to support that drop-down box!
public:
// NOTE: There are gotchas here: Since the script runs in its own eval{},
// variables declared with 'my' are transitory and local to the script. That is,
// if you declare 'my @myarray = (1,2,3);' and then run the script and followed by a
// call to getArrayVal("myarray", myarray), it will fail -- there is no longer any
// such list since the script has gone out of scope. But if you said something
// like '@myarray = (1,2,3);' and then used getArrayVal(), you will get a CStringArray
// with all 3 elements. Naturally, if you have 'use strict;' turned on, you will
// have to predeclare all 'globals' with the set*Val() functions or you will get
// errors.
// If there was a fatal error or exception in the script, this returns FALSE.
BOOL doScript(CString script); // execute the script, use other funcs to get results
// These are used to create and populate arbitrary variables.
// Good for setting up data to be processed by the script.
// They all return TRUE if the 'set' was successful.
BOOL setIntVal(CString varName, int value); // set scalar ($varName) to integer value
BOOL setFloatVal(CString varName, double value); // set scalar ($varName) to double value
BOOL setStringVal(CString varName, CString value); // set scalar ($varName) to string value
BOOL setArrayVal(CString varName, CStringArray &value); // set array (@varName) to CStringArray value
BOOL setHashVal(CString varName, const CMapStringToString &value); // set hash (%varName) to CMapStringToString value
// These are used to get the values of arbitrary variables ($a, $abc, @xyx, %gwxy, etc.)
// They all return TRUE if the variable was defined and set
BOOL getIntVal(CString varName, int &val); // get scalar ($varName) as an int
BOOL getFloatVal(CString varName, double &val); // get scalar ($varName) as a double
BOOL getStringVal(CString varName, CString &val); // get scalar ($varName) as a string
BOOL getArrayVal(CString varName, CStringArray &values); // get array (@varName) as a CStringArray
BOOL getHashVal(CString varName, CMapStringToString &value); // get hash (%varName) as a CMapStringToString
// These are used to get the return value of the SCRIPT passed to doScript(). Note
// that the return value of script is usually the value of the last line executed
// in that script. It isn't necessarily a TRUE or FALSE or such-like.
// This script was run in an eval() block to avoid adverse consequences if the script
// was flawed. So these functions get the return of the eval(). See the Perl manual
// for more details.
int getIntEval(void); // result of last doScript() as an integer
double getFloatEval(void); // result of last doScript() as a double
CString getStringEval(void); // result of last doScript() as a string
// If the doScript() call failed, this gets the error message from Perl.
// If doScript() succeeded, this returns an empty string. See definition of $@.
CString getErrorMsg(void) const;// last error from eval{} in doScript(), aka, $@
// Normally, warnings are sent to STDERR. But that isn't very useful in a Windows
// environment. So instead, they are saved in $__w_warnings. You can explicitly manipulate
// that variable or use these functions to access it.
//
// Warnings accumulate throughout the lifetime of the Perl instance, so you may want to
// use clearWarnings() to "start over". Or you could terminate the Perl instance and
// start a new one. But that wastes time and you lose ALL your variables. Alternatively,
// you can use SetclearWarningsOnScript() to automatically invoke clearWarnings() when
// you call doScript().
CString getWarnings(void); // get accumulated warnings ($__w_warnings)
void clearWarnings(void); // clear out accumulated warnings ($__w_warnings)
BOOL SetfailOnWarning(BOOL); // set to TRUE if warnings cause doScript() to return FALSE, returns previous setting
BOOL SetclearWarningsOnScript(BOOL); // set to TRUE if warnings are cleared before executing a doScript(), returns previous setting
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CPerlWrap)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CPerlWrap();
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_PERLWRAP_H__812B9B44_72D2_48FA_944D_76D7D4AA6E1D__INCLUDED_)