summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2013-09-10 09:54:14 -0700
committerEmiel Bruijntjes <emiel.bruijntjes@copernica.com>2013-09-10 09:54:14 -0700
commit37c38c70de43d9d9ee3c9f0e2f175e19bcc0b485 (patch)
tree29cf02cfabad5eb22306ac05eaee96efbdb79cd9
parent85507088051bdfabf8bc71346290949b78c3c914 (diff)
When registering functions, it now is also possible to specify the signature of the parameters
-rw-r--r--include/argument.h71
-rw-r--r--include/arguments.h98
-rw-r--r--include/byref.h60
-rw-r--r--include/byval.h60
-rw-r--r--include/extension.h25
-rw-r--r--include/function.h67
-rw-r--r--phpcpp.h3
-rw-r--r--src/argument.cpp104
-rw-r--r--src/arguments.cpp85
-rw-r--r--src/extension.cpp62
-rw-r--r--src/function.cpp40
-rw-r--r--src/includes.h5
-rw-r--r--src/nativefunction.h16
-rw-r--r--tests/simple/simple.cpp28
-rw-r--r--tests/simple/simple.php10
15 files changed, 357 insertions, 377 deletions
diff --git a/include/argument.h b/include/argument.h
index 7a95f7d..c29073d 100644
--- a/include/argument.h
+++ b/include/argument.h
@@ -4,6 +4,9 @@
* Class holds information about an argument that is passed to a function.
* You'll need this class when you're defining your own functions.
*
+ * The constructor of the argument is protected. Use the ByVal or ByRef
+ * classes instead.
+ *
* @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
* @copyright 2013 Copernica BV
*/
@@ -25,65 +28,49 @@ class Argument
{
public:
/**
- * Prevent copying
+ * Copy constructor
* @param argument
*/
- Argument(const Argument &argument) = delete;
-
+ Argument(const Argument &argument);
+
/**
* Move constructor
* @param argument
*/
Argument(Argument &&argument);
-
+
/**
* Destructor
*/
- virtual ~Argument() {};
-
- /**
- * Change the name
- * @param name
- * @return Argument
- */
- Argument &name(const char *name);
-
- /**
- * Change the type
- * @param type
- * @return Argument
- */
- Argument &type(Type type = nullType);
+ virtual ~Argument();
+protected:
/**
- * Require the parameter to be a certain class
- * @param name Name of the class
- * @param null Are null values allowed?
- * @return Argument
+ * Constructor
+ * @param name Name of the argument
+ * @param type Argument type
+ * @param required Is this argument required?
+ * @param byref Is this a reference argument
*/
- Argument &object(const char *classname, bool null = true);
+ Argument(const char *name, Type type, bool required = true, bool byref = false);
/**
- * Is this a by-ref argument?
- * @param bool Mark as by-ref variable
- * @return Argument
+ * Constructor
+ * @param name Name of the argument
+ * @param classname Name of the class
+ * @param nullable Can it be null?
+ * @param required Is this argument required?
+ * @param byref Is this a reference argument?
*/
- Argument &byref(bool value = true);
+ Argument(const char *name, const char *classname, bool nullable = true, bool required = true, bool byref = false);
+public:
/**
- * Prevent copy
- * @param argument The argument to copy
- * @return Argument
- */
- Argument &operator=(const Argument &argument) = delete;
-
-protected:
- /**
- * Protected constructor, to prevent that users can instantiate the
- * argument object themselves
+ * Fill an arg_info structure with data
* @param info
+ * @internal
*/
- Argument(struct _zend_arg_info *info) : _info(info) {}
+ void fill(struct _zend_arg_info *info) const;
private:
/**
@@ -91,6 +78,12 @@ private:
* @var zend_arg_info
*/
struct _zend_arg_info *_info;
+
+ /**
+ * Is this a required argument
+ * @var bool
+ */
+ bool _required;
};
/**
diff --git a/include/arguments.h b/include/arguments.h
deleted file mode 100644
index e57903f..0000000
--- a/include/arguments.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * Arguments.h
- *
- * When a function is invoked, it is passed a vector of arguments. This
- * arguments class, that overrides from vector, takes care of that.
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-
-/**
- * Forward declaration
- */
-struct _zend_arg_info;
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Class definition
- */
-class Arguments
-{
-public:
- /**
- * Constructor
- * @param min The min number of arguments
- * @param max The max number of arguments
- */
- Arguments(int min, int max);
-
- /**
- * No copy or move operations
- * @param arguments
- */
- Arguments(const Arguments &arguments) = delete;
- Arguments(Arguments &&arguments) = delete;
-
- /**
- * Destructor
- */
- virtual ~Arguments();
-
- /**
- * Number of arguments
- * @return int
- */
- int argc()
- {
- return _max;
- }
-
- /**
- * Number of required arguments
- * @return int
- */
- int required()
- {
- return _min;
- }
-
- /**
- * Get access to internal data
- * @return zend_arg_info*
- */
- struct _zend_arg_info *internal()
- {
- return _argv;
- }
-
-private:
- /**
- * Min number of arguments
- * @var integer
- */
- int _min;
-
- /**
- * Max number of arguments
- * @var integer
- */
- int _max;
-
- /**
- * The arguments
- * @var zend_arg_info[]
- */
- struct _zend_arg_info *_argv;
-
-};
-
-/**
- * End of namespace
- */
-}
-
diff --git a/include/byref.h b/include/byref.h
new file mode 100644
index 0000000..a10fff1
--- /dev/null
+++ b/include/byref.h
@@ -0,0 +1,60 @@
+/**
+ * ByRef.h
+ *
+ * Overridden Argument class to specify by-reference function arguments
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class ByRef : public Argument
+{
+public:
+ /**
+ * Constructor
+ * @param name Name of the argument
+ * @param type Argument type
+ * @param required Is this argument required?
+ */
+ ByRef(const char *name, Type type, bool required = true) : Argument(name, type, required, true) {}
+
+ /**
+ * Constructor
+ * @param name Name of the argument
+ * @param classname Name of the class
+ * @param nullable Can it be null?
+ * @param required Is this argument required?
+ */
+ ByRef(const char *name, const char *classname, bool nullable = true, bool required = true) : Argument(name, classname, nullable, required, true) {}
+
+ /**
+ * Copy constructor
+ * @param argument
+ */
+ ByRef(const ByRef &argument) : Argument(argument) {}
+
+ /**
+ * Move constructor
+ * @param argument
+ */
+ ByRef(ByRef &&argument) : Argument(argument) {}
+
+ /**
+ * Destructor
+ */
+ virtual ~ByRef() {}
+};
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/include/byval.h b/include/byval.h
new file mode 100644
index 0000000..a31c1f7
--- /dev/null
+++ b/include/byval.h
@@ -0,0 +1,60 @@
+/**
+ * ByVal.h
+ *
+ * Overridden Argument class to specify by-value function arguments
+ *
+ * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
+ * @copyright 2013 Copernica BV
+ */
+
+/**
+ * Namespace
+ */
+namespace Php {
+
+/**
+ * Class definition
+ */
+class ByVal : public Argument
+{
+public:
+ /**
+ * Constructor
+ * @param name Name of the argument
+ * @param type Argument type
+ * @param required Is this argument required?
+ */
+ ByVal(const char *name, Type type, bool required = true) : Argument(name, type, required, false) {}
+
+ /**
+ * Constructor
+ * @param name Name of the argument
+ * @param classname Name of the class
+ * @param nullable Can it be null?
+ * @param required Is this argument required?
+ */
+ ByVal(const char *name, const char *classname, bool nullable = true, bool required = true) : Argument(name, classname, nullable, required, false) {}
+
+ /**
+ * Copy constructor
+ * @param argument
+ */
+ ByVal(const ByVal &argument) : Argument(argument) {}
+
+ /**
+ * Move constructor
+ * @param argument
+ */
+ ByVal(ByVal &&argument) : Argument(argument) {}
+
+ /**
+ * Destructor
+ */
+ virtual ~ByVal() {}
+};
+
+/**
+ * End of namespace
+ */
+}
+
diff --git a/include/extension.h b/include/extension.h
index fb33c99..f5987e2 100644
--- a/include/extension.h
+++ b/include/extension.h
@@ -174,22 +174,23 @@ public:
* @param function The function to add
* @return Function The added function
*/
- Function &add(Function *function);
+ Function *add(Function *function);
/**
* Add a native function directly to the extension
* @param name Name of the function
* @param function The function to add
+ * @param arguments Optional argument specification
* @return Function The added function
*/
- Function &add(const char *name, native_callback_0 function);
- Function &add(const char *name, native_callback_1 function);
- Function &add(const char *name, native_callback_2 function);
- Function &add(const char *name, native_callback_3 function);
- Function &add(const char *name, native_callback_4 function);
- Function &add(const char *name, native_callback_5 function);
- Function &add(const char *name, native_callback_6 function);
- Function &add(const char *name, native_callback_7 function);
+ Function *add(const char *name, native_callback_0 function, const std::initializer_list<Argument> &arguments = {});
+ Function *add(const char *name, native_callback_1 function, const std::initializer_list<Argument> &arguments = {});
+ Function *add(const char *name, native_callback_2 function, const std::initializer_list<Argument> &arguments = {});
+ Function *add(const char *name, native_callback_3 function, const std::initializer_list<Argument> &arguments = {});
+ Function *add(const char *name, native_callback_4 function, const std::initializer_list<Argument> &arguments = {});
+ Function *add(const char *name, native_callback_5 function, const std::initializer_list<Argument> &arguments = {});
+ Function *add(const char *name, native_callback_6 function, const std::initializer_list<Argument> &arguments = {});
+ Function *add(const char *name, native_callback_7 function, const std::initializer_list<Argument> &arguments = {});
/**
* Retrieve the module entry
@@ -210,12 +211,6 @@ private:
std::set<std::unique_ptr<Function>> _functions;
/**
- * Hidden pointer to self
- * @var HiddenPointer
- */
- HiddenPointer<Extension> _ptr;
-
- /**
* The information that is passed to the Zend engine
*
* Although it would be slightly faster to not make this a pointer, this
diff --git a/include/function.h b/include/function.h
index c2dd9b8..ff4396c 100644
--- a/include/function.h
+++ b/include/function.h
@@ -32,60 +32,26 @@ public:
* @param min Min number of arguments
* @param max Max number of arguments
*/
- Function(const char *name, int min = 0, int max = 0) : _ptr(this, name)
- {
- // construct the arguments
- _arguments = std::shared_ptr<Arguments>(new Arguments(min, max));
- }
+ Function(const char *name, const std::initializer_list<Argument> &arguments = {});
/**
- * No copy constructor
- * @param function The other function
- */
- Function(const Function &function) : _ptr(this, function.name())
- {
- // copy members
- _arguments = function._arguments;
- _type = function._type;
- }
-
- /**
- * Move constructor
+ * No copy and move constructors
* @param function The other function
*/
- Function(Function &&function) : _ptr(this, function.name())
- {
- // copy arguments
- _arguments = function._arguments;
- _type = function._type;
-
- // no longer need the other arguments
- function._arguments.reset();
- }
+ Function(const Function &function) = delete;
+ Function(Function &&function) = delete;
/**
* Destructor
*/
- virtual ~Function() {}
+ virtual ~Function();
/**
- * Assignment operator
+ * No assignment operator
* @param function The other function
* @return Function
*/
- Function &operator=(const Function &function)
- {
- // skip self reference
- if (this == &function) return *this;
-
- // copy members
- _ptr.setText(function.name());
- _arguments = function._arguments;
- _type = function._type;
-
- // done
- return *this;
- }
+ Function &operator=(const Function &function) = delete;
/**
* Comparison
@@ -136,6 +102,7 @@ public:
{
return nullptr;
}
+
protected:
/**
@@ -144,11 +111,23 @@ protected:
*/
Type _type = nullType;
+ /**
+ * Required number of arguments
+ * @var integer
+ */
+ int _required;
+
+ /**
+ * Total number of arguments
+ * @var integer
+ */
+ int _argc;
+
/**
- * Pointer to the arguments
- * @var shared_ptr
+ * The arguments
+ * @var zend_arg_info[]
*/
- std::shared_ptr<Arguments> _arguments;
+ struct _zend_arg_info *_argv;
/**
* The name is stored in a hidden pointer, so that we have access to the function
diff --git a/phpcpp.h b/phpcpp.h
index 37660ec..db8a8e2 100644
--- a/phpcpp.h
+++ b/phpcpp.h
@@ -25,9 +25,10 @@
#include <phpcpp/type.h>
#include <phpcpp/request.h>
#include <phpcpp/argument.h>
+#include <phpcpp/byval.h>
+#include <phpcpp/byref.h>
#include <phpcpp/value.h>
#include <phpcpp/member.h>
-#include <phpcpp/arguments.h>
#include <phpcpp/parameters.h>
#include <phpcpp/function.h>
#include <phpcpp/extension.h>
diff --git a/src/argument.cpp b/src/argument.cpp
index 387151a..7dbf624 100644
--- a/src/argument.cpp
+++ b/src/argument.cpp
@@ -14,62 +14,102 @@
namespace Php {
/**
- * Move constructor
- * @param argument
+ * Constructor
+ * @param name Name of the argument
+ * @param type Argument type
+ * @param required Is this argument required?
+ * @param byref Is this a reference argument
*/
-Argument::Argument(Argument &&argument)
+Argument::Argument(const char *name, Type type, bool required, bool byref)
{
- // copy data
- _info = argument._info;
+ // construct object
+ _info = new zend_arg_info;
+
+ // fill members
+ _info->name = name;
+ _info->name_len = strlen(name);
+ _info->type_hint = type == arrayType || type == callableType ? type : 0;
+ _info->class_name = NULL;
+ _info->class_name_len = 0;
+ _info->allow_null = false;
+ _info->pass_by_reference = byref;
+
+ // store if required
+ _required = required;
}
/**
- * Change the name
- * @param name
- * @return Argument
+ * Constructor
+ * @param name Name of the argument
+ * @param classname Name of the class
+ * @param nullable Can it be null?
+ * @param required Is this argument required?
+ * @param byref Is this a reference argument?
*/
-Argument &Argument::name(const char *name)
+Argument::Argument(const char *name, const char *classname, bool nullable, bool required, bool byref)
{
+ // construct object
+ _info = new zend_arg_info;
+
+ // fill members
_info->name = name;
_info->name_len = strlen(name);
- return *this;
+ _info->type_hint = objectType;
+ _info->class_name = classname;
+ _info->class_name_len = strlen(classname);
+ _info->allow_null = nullable;
+ _info->pass_by_reference = byref;
+
+ // store if required
+ _required = required;
+}
+
+/**
+ * Copy constructor
+ * @param argument
+ */
+Argument::Argument(const Argument &argument)
+{
+ // construct object
+ _info = new zend_arg_info;
+
+ // fill members
+ *_info = *argument._info;
+
+ // store if required
+ _required = argument._required;
}
/**
- * Change the type
- * @param type
- * @return Argument
+ * Move constructor
+ * @param argument
*/
-Argument &Argument::type(Type type)
+Argument::Argument(Argument &&argument)
{
- _info->type_hint = type;
- return *this;
+ // copy memory pointer
+ _info = argument._info;
+
+ // forget in other object
+ argument._info = nullptr;
}
/**
- * Require the parameter to be a certain class
- * @param name Name of the class
- * @param null Are null values allowed?
- * @return Argument
+ * Destructor
*/
-Argument &Argument::object(const char *classname, bool null)
+Argument::~Argument()
{
- _info->type_hint = objectType;
- _info->class_name = classname;
- _info->class_name_len = strlen(classname);
- _info->allow_null = null;
- return *this;
+ if (_info) delete _info;
}
/**
- * Is this a by-ref argument?
- * @param bool Mark as by-ref variable
- * @return Argument
+ * Fill an arg_info structure with data
+ * @param info
+ * @internal
*/
-Argument &Argument::byref(bool value)
+void Argument::fill(struct _zend_arg_info *info) const
{
- _info->pass_by_reference = value;
- return *this;
+ // copy all data
+ *info = *_info;
}
/**
diff --git a/src/arguments.cpp b/src/arguments.cpp
deleted file mode 100644
index 53f030b..0000000
--- a/src/arguments.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/**
- * Arguments.cpp
- *
- * Implementation of the arguments class
- *
- * @author Emiel Bruijntjes <emiel.bruijntjes@copernica.com>
- * @copyright 2013 Copernica BV
- */
-#include "includes.h"
-
-/**
- * Set up namespace
- */
-namespace Php {
-
-/**
- * Constructor
- * @param min The min number of arguments
- * @param max The max number of arguments
- */
-Arguments::Arguments(int min, int max)
-{
- // copy arguments
- _min = min;
- _max = max;
-
- // max should be appropriate
- if (_max < _min) _max = _min;
-
- // allocate memory for the arguments, with one extra record to hold information
- _argv = new zend_arg_info[_max + 1];
-
- // initialize the arguments
- for (int i=1; i<_max+1; i++)
- {
- // initialize the argument
- _argv[i].name = NULL;
- _argv[i].name_len = 0;
- _argv[i].class_name = NULL;
- _argv[i].class_name_len = 0;
- _argv[i].type_hint = nullType;
- _argv[i].allow_null = false;
- _argv[i].pass_by_reference = false;
- }
-}
-
-/**
- * Destructor
- */
-Arguments::~Arguments()
-{
- // deallocate arguments
- delete[] _argv;
-}
-
-/**
- * Constructor
- * @param argc Number of arguments
- * @param tsrm_ls
- */
-/*
-
-Arguments::Arguments(int argc TSRMLS_DC)
-{
- // reserve plenty of space
- reserve(argc);
-
- // loop through the arguments
- for (int i=0; i<argc; i++)
- {
- // get the argument
- zval **arg = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 - (argc-i));
-
- // append value
- push_back(Value(*arg));
- }
-}
-*
-*/
-
-/**
- * End of namespace
- */
-}
-
diff --git a/src/extension.cpp b/src/extension.cpp
index a084763..9323bd3 100644
--- a/src/extension.cpp
+++ b/src/extension.cpp
@@ -20,6 +20,12 @@ namespace Php {
#endif
/**
+ * Pointer to the one and only extension object
+ * @var Extension
+ */
+static Extension *extension = nullptr;
+
+/**
* The way how PHP C API deals with "global" variables is stupid.
*
* This is supposed to turn into a structure that is going to be
@@ -68,21 +74,6 @@ static void php_phpcpp_init_globals(zend_phpcpp_globals *globals) {}
/**
- * Helper method to get back the current extension object
- * @return Extension
- */
-static Extension *get_extension()
-{
- // retrieve the extension or module name (because PHP of course does
- // not pass such extremely useful information as they've no clue how
- // to make a decent API
- zend_module_entry *module = EG(current_module);
-
- // the pointer to the extension is hidden in front of the name
- return HiddenPointer<Extension>(module->name);
-}
-
-/**
* Function that is called when the extension initializes
* @param type Module type
* @param number Module number
@@ -97,7 +88,7 @@ static int extension_startup(INIT_FUNC_ARGS)
// ZEND_INIT_MODULE_GLOBALS(hello, php_phpcpp_init_globals, NULL);
// initialize the extension
- return BOOL2SUCCESS(get_extension()->initialize());
+ return BOOL2SUCCESS(extension->initialize());
}
/**
@@ -108,11 +99,8 @@ static int extension_startup(INIT_FUNC_ARGS)
*/
static int extension_shutdown(SHUTDOWN_FUNC_ARGS)
{
- // @todo the get_extension() call crashes, we need a different way to find the extension
- return 0;
-
// finalize the extension
- return BOOL2SUCCESS(get_extension()->finalize());
+ return BOOL2SUCCESS(extension->finalize());
}
/**
@@ -124,7 +112,7 @@ static int extension_shutdown(SHUTDOWN_FUNC_ARGS)
static int request_startup(INIT_FUNC_ARGS)
{
// create the request
- return BOOL2SUCCESS(get_extension()->startRequest());
+ return BOOL2SUCCESS(extension->startRequest());
}
/**
@@ -135,11 +123,8 @@ static int request_startup(INIT_FUNC_ARGS)
*/
static int request_shutdown(INIT_FUNC_ARGS)
{
- // @todo the get_extension() call crashes, we need a different way to find the extension
- return 0;
-
// end the request
- return BOOL2SUCCESS(get_extension()->endRequest());
+ return BOOL2SUCCESS(extension->endRequest());
}
@@ -148,8 +133,11 @@ static int request_shutdown(INIT_FUNC_ARGS)
* @param name Name of the extension
* @param version Version number
*/
-Extension::Extension(const char *name, const char *version) : _ptr(this, name)
+Extension::Extension(const char *name, const char *version)
{
+ // store extension variable
+ extension = this;
+
// allocate memory (we allocate this on the heap so that the size of the
// entry does not have to be defined in the .h file. We pay a performance
// price for this, but we pay this price becuase the design goal of the
@@ -163,7 +151,7 @@ Extension::Extension(const char *name, const char *version) : _ptr(this, name)
_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 = _ptr; // extension name, with a hidden pointer to the extension object
+ _entry->name = name; // extension name
_entry->functions = NULL; // functions supported by this module (none for now)
_entry->module_startup_func = extension_startup; // startup function for the whole extension
_entry->module_shutdown_func = extension_shutdown; // shutdown function for the whole extension
@@ -208,13 +196,13 @@ Extension::~Extension()
* @param function Function object
* @return Function
*/
-Function &Extension::add(Function *function)
+Function *Extension::add(Function *function)
{
// add the function to the map
_functions.insert(std::unique_ptr<Function>(function));
// the result is a pair with an iterator
- return *function;
+ return function;
}
/**
@@ -223,14 +211,14 @@ Function &Extension::add(Function *function)
* @param function The function to add
* @return Function The added function
*/
-Function &Extension::add(const char *name, native_callback_0 function) { return add(new NativeFunction(name, function)); }
-Function &Extension::add(const char *name, native_callback_1 function) { return add(new NativeFunction(name, function)); }
-Function &Extension::add(const char *name, native_callback_2 function) { return add(new NativeFunction(name, function)); }
-Function &Extension::add(const char *name, native_callback_3 function) { return add(new NativeFunction(name, function)); }
-Function &Extension::add(const char *name, native_callback_4 function) { return add(new NativeFunction(name, function)); }
-Function &Extension::add(const char *name, native_callback_5 function) { return add(new NativeFunction(name, function)); }
-Function &Extension::add(const char *name, native_callback_6 function) { return add(new NativeFunction(name, function)); }
-Function &Extension::add(const char *name, native_callback_7 function) { return add(new NativeFunction(name, function)); }
+Function *Extension::add(const char *name, native_callback_0 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); }
+Function *Extension::add(const char *name, native_callback_1 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); }
+Function *Extension::add(const char *name, native_callback_2 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); }
+Function *Extension::add(const char *name, native_callback_3 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); }
+Function *Extension::add(const char *name, native_callback_4 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); }
+Function *Extension::add(const char *name, native_callback_5 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); }
+Function *Extension::add(const char *name, native_callback_6 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); }
+Function *Extension::add(const char *name, native_callback_7 function, const std::initializer_list<Argument> &arguments) { return add(new NativeFunction(name, function, arguments)); }
/**
* Retrieve the module entry
diff --git a/src/function.cpp b/src/function.cpp
index f15bffd..755bb48 100644
--- a/src/function.cpp
+++ b/src/function.cpp
@@ -45,6 +45,40 @@ void invoke_function(INTERNAL_FUNCTION_PARAMETERS)
}
/**
+ * Constructor
+ * @param name Name of the function
+ * @param min Min number of arguments
+ * @param max Max number of arguments
+ */
+Function::Function(const char *name, const std::initializer_list<Argument> &arguments) : _ptr(this, name)
+{
+ // construct vector for arguments
+ _argc = arguments.size();
+ _argv = new zend_arg_info[_argc+1];
+
+ // counter
+ int i=1;
+
+ // loop through the arguments
+ for (auto it = arguments.begin(); it != arguments.end(); it++)
+ {
+ // fill the arg info
+ it->fill(&_argv[i++]);
+ }
+
+ // @todo find out number of required arguments
+ _required = _argc;
+}
+
+/**
+ * Destructor
+ */
+Function::~Function()
+{
+ delete[] _argv;
+}
+
+/**
* Fill a function entry
*
* This method is called when the extension is registering itself, when the
@@ -57,8 +91,8 @@ void Function::fill(zend_function_entry *entry) const
// fill the members of the entity, and hide a pointer to the current object in the name
entry->fname = _ptr;
entry->handler = invoke_function;
- entry->arg_info = _arguments->internal();
- entry->num_args = _arguments->argc();
+ entry->arg_info = _argv;
+ entry->num_args = _argc;
// there are no flags like deprecated, private or protected
entry->flags = 0;
@@ -81,7 +115,7 @@ void Function::fill(zend_internal_function_info *info) const
info->_class_name = NULL;
// number of required arguments, and the expected return type
- info->required_num_args = _arguments->required();
+ info->required_num_args = _required;
info->_type_hint = _type;
// we do not support return-by-reference
diff --git a/src/includes.h b/src/includes.h
index 3c1f26f..22f2891 100644
--- a/src/includes.h
+++ b/src/includes.h
@@ -24,7 +24,7 @@
/**
* PHP includes
*/
-#include "php.h"
+#include <php.h>
/**
* Macro to convert results to success status
@@ -38,9 +38,10 @@
#include "../include/type.h"
#include "../include/request.h"
#include "../include/argument.h"
+#include "../include/byval.h"
+#include "../include/byref.h"
#include "../include/value.h"
#include "../include/member.h"
-#include "../include/arguments.h"
#include "../include/parameters.h"
#include "../include/function.h"
#include "../include/extension.h"
diff --git a/src/nativefunction.h b/src/nativefunction.h
index 40b8539..e8281ce 100644
--- a/src/nativefunction.h
+++ b/src/nativefunction.h
@@ -24,14 +24,14 @@ public:
* @param name Function name
* @param function The native C function
*/
- NativeFunction(const char *name, native_callback_0 function) : Function(name), _type(0) { _function.f0 = function; _ptr.setPointer(this); }
- NativeFunction(const char *name, native_callback_1 function) : Function(name), _type(1) { _function.f1 = function; _ptr.setPointer(this); }
- NativeFunction(const char *name, native_callback_2 function) : Function(name), _type(2) { _function.f2 = function; _ptr.setPointer(this); }
- NativeFunction(const char *name, native_callback_3 function) : Function(name), _type(3) { _function.f3 = function; _ptr.setPointer(this); }
- NativeFunction(const char *name, native_callback_4 function) : Function(name), _type(4) { _function.f4 = function; _ptr.setPointer(this); }
- NativeFunction(const char *name, native_callback_5 function) : Function(name), _type(5) { _function.f5 = function; _ptr.setPointer(this); }
- NativeFunction(const char *name, native_callback_6 function) : Function(name), _type(6) { _function.f6 = function; _ptr.setPointer(this); }
- NativeFunction(const char *name, native_callback_7 function) : Function(name), _type(7) { _function.f7 = function; _ptr.setPointer(this); }
+ NativeFunction(const char *name, native_callback_0 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(0) { _function.f0 = function; }
+ NativeFunction(const char *name, native_callback_1 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(1) { _function.f1 = function; }
+ NativeFunction(const char *name, native_callback_2 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(2) { _function.f2 = function; }
+ NativeFunction(const char *name, native_callback_3 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(3) { _function.f3 = function; }
+ NativeFunction(const char *name, native_callback_4 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(4) { _function.f4 = function; }
+ NativeFunction(const char *name, native_callback_5 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(5) { _function.f5 = function; }
+ NativeFunction(const char *name, native_callback_6 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(6) { _function.f6 = function; }
+ NativeFunction(const char *name, native_callback_7 function, const std::initializer_list<Argument> &arguments = {}) : Function(name, arguments), _type(7) { _function.f7 = function; }
/**
* Destructor
diff --git a/tests/simple/simple.cpp b/tests/simple/simple.cpp
index 954bfa9..2ab177f 100644
--- a/tests/simple/simple.cpp
+++ b/tests/simple/simple.cpp
@@ -17,16 +17,8 @@ using namespace std;
static Php::Value my_plus(Php::Parameters &params)
{
- cout << "my_plus called" << endl;
-
- cout << "params: " << params.size() << endl;
-
string p1 = params[0];
string p2 = params[1];
-
- cout << "p1: " << p1 << endl;
- cout << "p2: " << p2 << endl;
-
return p1 + p2;
}
@@ -35,9 +27,15 @@ class MyCustomFunction : public Php::Function
public:
MyCustomFunction(const char *name) : Function(name) {}
+
};
+
+
+
+
+
// symbols are exported according to the "C" language
extern "C"
{
@@ -47,13 +45,19 @@ extern "C"
// create extension
static Php::Extension extension("simple","1.0");
- // define the functions
- extension.add("my_plus", my_plus);
- extension.add("my_concat", my_concat);
+ // define the functionsnm
+ extension.add("my_plus", my_plus, {
+ Php::ByVal("a", Php::stringType),
+ Php::ByVal("b", Php::arrayType),
+ Php::ByVal("c", "MyClass"),
+ Php::ByRef("d", Php::stringType)
+ });
+
+// extension.add("my_concat", my_concat);
extension.add(new MyCustomFunction("my_custom"));
// define classes
-// extension.add("my_class", MyCustomClass());
+// extension.add("my_class", MyCustomClass());
// return the module entry
return extension.module();
diff --git a/tests/simple/simple.php b/tests/simple/simple.php
index a6bf7f5..6f70a7a 100644
--- a/tests/simple/simple.php
+++ b/tests/simple/simple.php
@@ -10,7 +10,15 @@ class XXX
$myvar = "hoi";
-$result = my_plus($myvar, 1, 2, 3, "blabla", new XXX());
+class MyClass {
+
+ public function __toString()
+ {
+ return "aksjdfhsdfkj";
+ }
+}
+
+$result = my_plus(new MyClass(), array(), new MyClass(), $myvar, "blabla", new XXX());
echo("myvar = $myvar\n");