From: <vm...@us...> - 2009-06-15 10:23:35
|
Revision: 11254 http://swig.svn.sourceforge.net/swig/?rev=11254&view=rev Author: vmiklos Date: 2009-06-15 10:23:28 +0000 (Mon, 15 Jun 2009) Log Message: ----------- PHP: Add 'extend' example, based on the Python one Added Paths: ----------- branches/gsoc2009-vmiklos/Examples/php/extend/ branches/gsoc2009-vmiklos/Examples/php/extend/Makefile branches/gsoc2009-vmiklos/Examples/php/extend/example.cxx branches/gsoc2009-vmiklos/Examples/php/extend/example.h branches/gsoc2009-vmiklos/Examples/php/extend/example.i branches/gsoc2009-vmiklos/Examples/php/extend/index.html branches/gsoc2009-vmiklos/Examples/php/extend/runme.php Added: branches/gsoc2009-vmiklos/Examples/php/extend/Makefile =================================================================== --- branches/gsoc2009-vmiklos/Examples/php/extend/Makefile (rev 0) +++ branches/gsoc2009-vmiklos/Examples/php/extend/Makefile 2009-06-15 10:23:28 UTC (rev 11254) @@ -0,0 +1,22 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' php_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='myphp' INTERFACE='$(INTERFACE)' php_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile php_clean + rm -f $(TARGET).php + +check: all + $(MAKE) -f $(TOP)/Makefile php_run Added: branches/gsoc2009-vmiklos/Examples/php/extend/example.cxx =================================================================== --- branches/gsoc2009-vmiklos/Examples/php/extend/example.cxx (rev 0) +++ branches/gsoc2009-vmiklos/Examples/php/extend/example.cxx 2009-06-15 10:23:28 UTC (rev 11254) @@ -0,0 +1,4 @@ +/* File : example.cxx */ + +#include "example.h" + Added: branches/gsoc2009-vmiklos/Examples/php/extend/example.h =================================================================== --- branches/gsoc2009-vmiklos/Examples/php/extend/example.h (rev 0) +++ branches/gsoc2009-vmiklos/Examples/php/extend/example.h 2009-06-15 10:23:28 UTC (rev 11254) @@ -0,0 +1,56 @@ +/* File : example.h */ + +#include <cstdio> +#include <iostream> +#include <vector> +#include <string> +#include <cmath> + +class Employee { +private: + std::string name; +public: + Employee(const char* n): name(n) {} + virtual std::string getTitle() { return getPosition() + " " + getName(); } + virtual std::string getName() { return name; } + virtual std::string getPosition() const { return "Employee"; } + virtual ~Employee() { printf("~Employee() @ %p\n", this); } +}; + + +class Manager: public Employee { +public: + Manager(const char* n): Employee(n) {} + virtual std::string getPosition() const { return "Manager"; } +}; + + +class EmployeeList { + std::vector<Employee*> list; +public: + EmployeeList() { + list.push_back(new Employee("Bob")); + list.push_back(new Employee("Jane")); + list.push_back(new Manager("Ted")); + } + void addEmployee(Employee *p) { + list.push_back(p); + std::cout << "New employee added. Current employees are:" << std::endl; + std::vector<Employee*>::iterator i; + for (i=list.begin(); i!=list.end(); i++) { + std::cout << " " << (*i)->getTitle() << std::endl; + } + } + const Employee *get_item(int i) { + return list[i]; + } + ~EmployeeList() { + std::vector<Employee*>::iterator i; + std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl; + for (i=list.begin(); i!=list.end(); i++) { + delete *i; + } + std::cout << "~EmployeeList empty." << std::endl; + } +}; + Added: branches/gsoc2009-vmiklos/Examples/php/extend/example.i =================================================================== --- branches/gsoc2009-vmiklos/Examples/php/extend/example.i (rev 0) +++ branches/gsoc2009-vmiklos/Examples/php/extend/example.i 2009-06-15 10:23:28 UTC (rev 11254) @@ -0,0 +1,15 @@ +/* File : example.i */ +%module(directors="1") example +%{ +#include "example.h" +%} + +%include "std_vector.i" +%include "std_string.i" + +/* turn on director wrapping for Manager */ +%feature("director") Employee; +%feature("director") Manager; + +%include "example.h" + Added: branches/gsoc2009-vmiklos/Examples/php/extend/index.html =================================================================== --- branches/gsoc2009-vmiklos/Examples/php/extend/index.html (rev 0) +++ branches/gsoc2009-vmiklos/Examples/php/extend/index.html 2009-06-15 10:23:28 UTC (rev 11254) @@ -0,0 +1,19 @@ +<html> +<head> +<title>SWIG:Examples:php:extend</title> +</head> + +<body bgcolor="#ffffff"> + + +<tt>SWIG/Examples/php/extend/</tt> +<hr> + +<H2>Extending a simple C++ class in PHP</H2> + +<p> +This example illustrates the extending of a C++ class with cross language polymorphism. + +<hr> +</body> +</html> Added: branches/gsoc2009-vmiklos/Examples/php/extend/runme.php =================================================================== --- branches/gsoc2009-vmiklos/Examples/php/extend/runme.php (rev 0) +++ branches/gsoc2009-vmiklos/Examples/php/extend/runme.php 2009-06-15 10:23:28 UTC (rev 11254) @@ -0,0 +1,76 @@ +<?php + +# This file illustrates the cross language polymorphism using directors. + +require("example.php"); + +# CEO class, which overrides Employee::getPosition(). + +class CEO extends Manager { + function getPosition() { + return "CEO"; + } +} + +# Create an instance of our employee extension class, CEO. The calls to +# getName() and getPosition() are standard, the call to getTitle() uses +# the director wrappers to call CEO.getPosition. + +$e = new CEO("Alice"); +print $e->getName() . " is a " . $e->getPosition() . "\n"; +printf("Just call her \"%s\"\n", $e->getTitle()); +print "----------------------\n"; + +# Create a new EmployeeList instance. This class does not have a C++ +# director wrapper, but can be used freely with other classes that do. + +$list = new EmployeeList(); + +# EmployeeList owns its items, so we must surrender ownership of objects +# we add. This involves first clearing the ->disown member to tell the +# C++ director to start reference counting. + +$e->thisown = 0; +$list->addEmployee($e); +print "----------------------\n"; + +# Now we access the first four items in list (three are C++ objects that +# EmployeeList's constructor adds, the last is our CEO). The virtual +# methods of all these instances are treated the same. For items 0, 1, and +# 2, both all methods resolve in C++. For item 3, our CEO, getTitle calls +# getPosition which resolves in PHP. The call to getPosition is +# slightly different, however, from the e.getPosition() call above, since +# now the object reference has been "laundered" by passing through +# EmployeeList as an Employee*. Previously, PHP resolved the call +# immediately in CEO, but now PHP thinks the object is an instance of +# class Employee (actually EmployeePtr). So the call passes through the +# Employee proxy class and on to the C wrappers and C++ director, +# eventually ending up back at the CEO implementation of getPosition(). +# The call to getTitle() for item 3 runs the C++ Employee::getTitle() +# method, which in turn calls getPosition(). This virtual method call +# passes down through the C++ director class to the PHP implementation +# in CEO. All this routing takes place transparently. + +print "(position, title) for items 0-3:\n"; + +printf(" %s, \"%s\"\n", $list->get_item(0)->getPosition(), $list->get_item(0)->getTitle()); +printf(" %s, \"%s\"\n", $list->get_item(1)->getPosition(), $list->get_item(1)->getTitle()); +printf(" %s, \"%s\"\n", $list->get_item(2)->getPosition(), $list->get_item(2)->getTitle()); +printf(" %s, \"%s\"\n", $list->get_item(3)->getPosition(), $list->get_item(3)->getTitle()); +print "----------------------\n"; + +# Time to delete the EmployeeList, which will delete all the Employee* +# items it contains. The last item is our CEO, which gets destroyed as its +# reference count goes to zero. The PHP destructor runs, and is still +# able to call the getName() method since the underlying C++ object still +# exists. After this destructor runs the remaining C++ destructors run as +# usual to destroy the object. + +unset($list); +print "----------------------\n"; + +# All done. + +print "php exit\n"; + +?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |