summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2013-08-24 19:44:19 +0200
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2013-08-24 19:44:19 +0200
commitb8a14d96c06d5a8910cb28d28870f0036ae6a461 (patch)
tree5077e7af0a04ce093dded091747c047b1ad05478
parentd29c1a960798bbfa351b1aa3426d6f0a79ffe92c (diff)
The extension::initialize() and extension::finalize() methods are called at the appropriate time
-rw-r--r--Makefile6
-rw-r--r--include/extension.h51
-rw-r--r--phpcpp.h13
-rw-r--r--src/extension.cpp112
-rw-r--r--src/includes.h14
-rw-r--r--tests/simple/simple.cpp30
6 files changed, 176 insertions, 50 deletions
diff --git a/Makefile b/Makefile
index 2eb652a..53aec7a 100644
--- a/Makefile
+++ b/Makefile
@@ -5,9 +5,13 @@ LIBRARY_DIR = ${PREFIX}/lib
all:
cd src; $(MAKE)
+tests:
+ cd tests; $(MAKE)
+
clean:
cd src; $(MAKE) clean
-
+ cd tests; $(MAKE) clean
+
install:
mkdir -p ${INCLUDE_DIR}/phpcpp
mkdir -p ${LIBRARY_DIR}
diff --git a/include/extension.h b/include/extension.h
index 69d5d3c..3a852ac 100644
--- a/include/extension.h
+++ b/include/extension.h
@@ -13,10 +13,14 @@
*/
/**
+ * Forward declarations
+ */
+struct _zend_module_entry;
+
+/**
* Set up namespace
*/
-namespace PhpCpp
-{
+namespace PhpCpp {
/**
* Class definition
@@ -26,15 +30,15 @@ class Extension
public:
/**
* Constructor
+ * @param name Extension name
+ * @param version EXtension version
*/
- Extension();
+ Extension(const char *name, const char *version);
/**
* Destructor
*/
- virtual ~Extension()
- {
- }
+ virtual ~Extension();
/**
* Initialize the extension.
@@ -46,7 +50,7 @@ public:
* The method should return true on success, and false on failure (in which
* case the extension will not be used)
*
- * @return boolean
+ * @return bool
*/
virtual bool initialize()
{
@@ -59,12 +63,41 @@ public:
* This method gets called after all requests were handled, and right before
* the Apache module or CLI script will exit. You can override it to add
* your own cleanup code.
+ *
+ * @return bool
*/
- virtual void finalize()
+ virtual bool finalize()
{
+ return true;
}
-
+
+ /**
+ * Internal method to get access to the entry
+ * @return zend_module_entry
+ */
+ _zend_module_entry *entry();
+
private:
+ /**
+ * Extension name
+ * @var char*
+ */
+ const char *_name;
+
+ /**
+ * Extension version
+ * @var char*
+ */
+ const char *_version;
+
+ /**
+ * The information that is passed to the Zend engine
+ * @var zend_module_entry
+ */
+ _zend_module_entry *_entry;
+
+
+
};
diff --git a/phpcpp.h b/phpcpp.h
index 439b51f..2a8517a 100644
--- a/phpcpp.h
+++ b/phpcpp.h
@@ -12,4 +12,17 @@
*/
#include <phpcpp/extension.h>
+/**
+ * Macro to export a function
+ */
+#if defined(__GNUC__) && __GNUC__ >= 4
+# define PHPCPP_EXPORT __attribute__ ((visibility("default")))
+#else
+# define PHPCPP_EXPORT
+#endif
+
+/**
+ * Macro to activate the extension
+ */
+#define PHP_CPP_EXTENSION(classname) extern "C" { PHPCPP_EXPORT void *get_module() { static classname extension; return extension.entry(); } }
diff --git a/src/extension.cpp b/src/extension.cpp
index 1677ec1..0a7def6 100644
--- a/src/extension.cpp
+++ b/src/extension.cpp
@@ -12,40 +12,98 @@
namespace PhpCpp {
/**
+ * Pointer to the one and only extension
+ * @var Extension
+ */
+static Extension *extension;
+
+/**
* Constructor
* @param name Name of the extension
* @param version Version number
*/
-Extension::Extension(const char *name, const char *version)
+Extension::Extension(const char *name, const char *version) : _name(name), _version(version), _entry(NULL)
+{
+ // store pointer to the one and only extension
+ extension = this;
+}
+
+/**
+ * Destructor
+ */
+Extension::~Extension()
+{
+ // deallocate entry
+ if (_entry) delete _entry;
+}
+
+/**
+ * Function that is called when the extension initializes
+ * @param type Module type
+ * @param number Module number
+ * @param tsrm_ls Optional thread safety thing
+ * @return int 0 on success
+ */
+static int extension_startup(INIT_FUNC_ARGS)
+{
+ return BOOL2SUCCESS(extension->initialize());
+}
+
+/**
+ * Function that is called when the extension is about to be stopped
+ * @param type Module type
+ * @param number Module number
+ * @return int
+ */
+static int extension_shutdown(SHUTDOWN_FUNC_ARGS)
+{
+ return BOOL2SUCCESS(extension->finalize());
+}
+
+/**
+ * Retrieve a pointer to the entry
+ * @return zend_module_entry
+ */
+zend_module_entry *Extension::entry()
{
- // initialize the entry
- _entry.size = sizeof(zend_module_entry); // size of the data
- _entry.zend_api = ZEND_MODULE_API_NO; // api number
- _entry.zend_debug = ZEND_DEBUG; // debug mode enabled?
- _entry.zts = USING_ZTS; // is thread safety enabled?
- _entry.ini_entry = NULL; // the php.ini record
- _entry.deps = NULL; // dependencies on other modules
- _entry.name = name; // extension name
- _entry.functions = NULL; // functions supported by this module
- _entry.module_startup_func = NULL; // startup function for the whole extension
- _entry.module_shutdown_func = NULL; // shutdown function for the whole extension
- _entry.request_startup_func = NULL; // startup function per request
- _entry.request_shutdown_func = NULL; // shutdown function per request
- _entry.info_func = NULL; // information for retrieving info
- _entry.version = version; // version string
- _entry.globals_size = 0; // number of global variables
+ // already initialized?
+ if (_entry) return _entry;
+
+ // allocate now
+ _entry = new zend_module_entry;
+
+ // assign all members
+ _entry->size = sizeof(zend_module_entry); // size of the data
+ _entry->zend_api = ZEND_MODULE_API_NO; // api number
+ _entry->zend_debug = ZEND_DEBUG; // debug mode enabled?
+ _entry->zts = USING_ZTS; // is thread safety enabled?
+ _entry->ini_entry = NULL; // the php.ini record
+ _entry->deps = NULL; // dependencies on other modules
+ _entry->name = _name; // extension name
+ _entry->functions = NULL; // functions supported by this module
+ _entry->module_startup_func = extension_startup; // startup function for the whole extension
+ _entry->module_shutdown_func = extension_shutdown; // shutdown function for the whole extension
+ _entry->request_startup_func = NULL; // startup function per request
+ _entry->request_shutdown_func = NULL; // shutdown function per request
+ _entry->info_func = NULL; // information for retrieving info
+ _entry->version = _version; // version string
+ _entry->globals_size = 0; // number of global variables
#ifdef ZTS
- _entry.globals_id_ptr = NULL; // pointer to the globals, thread safe
+ _entry->globals_id_ptr = NULL; // pointer to the globals, thread safe
#else
- _entry.globals_ptr = NULL; // pointer to the globals
- _entry.globals_ctor = NULL; // constructor for global variables
- _entry.globals_dtor = NULL; // destructor for global variables
- _entry.post_deactivate_func = NULL; // unknown function
- _entry.module_started = 0; // module is not yet started
- _entry.type = 0; // temporary or persistent module, will be filled by Zend engine
- _entry.handle = NULL; // dlopen() handle, will be filled by Zend engine
- _entry.module_number = 0; // module number will be filled in by Zend engine
- _entry.build_id = ZEND_MODULE_BUILD_ID; // check if extension and zend engine are compatible
+ _entry->globals_ptr = NULL; // pointer to the globals
+#endif
+ _entry->globals_ctor = NULL; // constructor for global variables
+ _entry->globals_dtor = NULL; // destructor for global variables
+ _entry->post_deactivate_func = NULL; // unknown function
+ _entry->module_started = 0; // module is not yet started
+ _entry->type = 0; // temporary or persistent module, will be filled by Zend engine
+ _entry->handle = NULL; // dlopen() handle, will be filled by Zend engine
+ _entry->module_number = 0; // module number will be filled in by Zend engine
+ _entry->build_id = ZEND_MODULE_BUILD_ID; // check if extension and zend engine are compatible
+
+ // done
+ return _entry;
}
/**
diff --git a/src/includes.h b/src/includes.h
index 385d033..5d8fb8c 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -11,11 +11,19 @@
* Include standard C and C++ libraries
*/
#include <stdlib.h>
-#include <php5/main/php.h>
-#include <php5/main/php_ini.h>
+
+/**
+ * PHP includes
+ */
+#include "php.h"
+
+/**
+ * Macro to convert results to success status
+ */
+#define BOOL2SUCCESS(b) ((b) ? SUCCESS : FAILURE)
/**
* Include other files from this library
- */
+ */
#include "../include/extension.h"
diff --git a/tests/simple/simple.cpp b/tests/simple/simple.cpp
index 36db294..fbfcbf8 100644
--- a/tests/simple/simple.cpp
+++ b/tests/simple/simple.cpp
@@ -7,6 +7,12 @@
* @copyright 2013 Copernica BV
*/
#include <phpcpp.h>
+#include <iostream>
+
+/**
+ * Namespace to use
+ */
+using namespace std;
/**
* Override the extension class
@@ -17,19 +23,23 @@ public:
/**
* Constructor
*/
- SimpleExtension() : Extension(
- "simple",
- "1.0",
- "Emiel Bruijntjes <emiel.bruijntjes@copernica.com>",
- "http://www.copernica.com",
- "Copyright 2013 Copernica BV")
+ SimpleExtension() : Extension("simple", "1.0")
+ {
+ }
+
+ virtual bool initialize()
{
+ cout << "initialize" << endl;
+ return true;
}
+
+ virtual bool finalize()
+ {
+ cout << "finalize" << endl;
+ return true;
+ }
+
};
-extern "C" {
-
// create the object for the PHP extension
PHP_CPP_EXTENSION(SimpleExtension);
-
-}