diff options
author | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2015-01-16 13:40:49 +0100 |
---|---|---|
committer | Emiel Bruijntjes <emiel.bruijntjes@copernica.com> | 2015-01-16 13:40:49 +0100 |
commit | 9390addb0798598d7b333dcc86487caf0117a231 (patch) | |
tree | 46f6eecefcad4ecade3fa09debca7304c1ed14bb /documentation | |
parent | d87b3ca8f1dbcb395f2dfd6540483da7a0e5e15c (diff) |
added documentation about lambda functions
Diffstat (limited to 'documentation')
-rw-r--r-- | documentation/lambda-functions.html | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/documentation/lambda-functions.html b/documentation/lambda-functions.html new file mode 100644 index 0000000..19b7775 --- /dev/null +++ b/documentation/lambda-functions.html @@ -0,0 +1,208 @@ +<h1>Lambda functions</h1> +<p> + C++ and PHP both support lambda functions or anonumous functions (in + the C++ world the word 'lambda' is most used, PHP people speak about + 'anonymous functions'). With PHP-CPP you can pass these functions + from one language to the other. It is possible to call an anonymous + PHP function from your C++ code, and the other way around, to call a C++ + lambda from a PHP script. +</p> +<h2>Calling anonymous PHP functions from C++</h2> +<p> + Let's start with a very simple example in PHP. In PHP you can create + anonymous functions, and assign them to a variable (or pass them + directly to a function). +</p> +<p> +<pre class="language-php"><code><php +// anonymous PHP function stored in the variable $f +$f = function($a, $b) { + + // return the sum of the parameters + return $a + $b; +} + +// pass the function to another function +other_function($f); + +// or pass an anonymous function without assigning it to a variable +other_function(function() { + + // return the product of the parameters + return $a * $b; +}); + +?> +</code></pre> +</p> +<p> + The code above should be familiar to most PHP programmers. The + 'other_function' can of course be implemented in PHP user space, + but to demonstrate how to do this with PHP-CPP we are going to + build it with C++. Just like all the other functions that you've + seen in the earlier examples, such a C++ function function receives + a vector of Php::Value objects as its parameters. +</p> +<p> +<pre class="language-c++"><code>#include <phpcpp.h> +/** + * Native function that is callable from PHP + * + * This function gets one parameter that holds a callable anonynous + * PHP function. + * + * @param params The parameters passed to the function + */ +void other_function(Php::Parameters &params) +{ + // first parameter is an anonymous function + Php::Value func = params[0]; + + // the Php::Value class has implemented the operator (), which allows + // us to use the object just as if it is a real function. + Php::Value result = func(3, 4); + + // @todo do something with the result +} + +/** + * Switch to C context, because the Zend engine expects the get_module() + * to have a C style function signature + */ +extern "C" { + /** + * Startup function that is automatically called by the Zend engine + * when PHP starts, and that should return the extension details + * @return void* + */ + PHPCPP_EXPORT void *get_module() + { + // the extension object + static Php::Extension extension("my_extension", "1.0"); + + // add the example function so that it can be called from PHP scripts + extension.add("other_function", other_function); + + // return the extension details + return extension; + } +}</code></pre> +</p> +<p> + It is that simple. But the other way around is possible too. Imagine + we have a function in PHP user space code that accepts a function + as it's parameter: +</p> +<p> +<pre class="language-php"><code><php +// function that iterates over an array, and calls a function on every +// element in that array, it returns a new array with every item +// replaced by the result of the callback +function my_iterate($array, $callback) { + + // initial result variable + $result = array(); + + // loop through the array + foreach ($array as $index => $item) { + + // call the callback on the item + $result[$index] = $callback($item); + } + + // done + return $result; +} +<?> +</code></pre> +</p> +<p> + Imagine that we want to call this PHP function from your C++ code, + using a C++ lambda function as a callback. This is possible, and easy: +</p> +<p> +<pre class="language-c++"><code>#include <phpcpp.h> +/** + * Native function that is callable from PHP + */ +void run_test() +{ + // create the anonymous function + Php::Function multiply_by_two([](Php::Parameters &params) -> Php::Value) { + + // make sure the function was really called with one parameter + if (params.size() == 0) return nullptr; + + // one parameter is passed to the function + Php::Value param = params[0]; + + // multiple the parameter by two + return params * 2; + }); + + // the function now is callable + Php::Value four = multiply_by_two(2); + + // a Php::Function object is a derived Php::Value, and can be used + // as a normal Php::Value object - it just happen to store a callback, + // it can also be stored in a Php::Value object, without losing + // anything + Php::Value value = multiply_by_two; + + // the value object now also holds a function + Php::Value six = value(3); + + // create an array + Php::Value array; + array[0] = 1; + array[1] = 2; + array[2] = 3; + array[3] = 4; + + // call the user-space function + Php::Value result = Php::call("my_iterate", array, multiply_by_two); + + // @todo do something with the result variable (which now holds + // an array with values 2, 4, 6 and 8). +} + +/** + * Switch to C context, because the Zend engine expects the get_module() + * to have a C style function signature + */ +extern "C" { + /** + * Startup function that is automatically called by the Zend engine + * when PHP starts, and that should return the extension details + * @return void* + */ + PHPCPP_EXPORT void *get_module() + { + // the extension object + static Php::Extension extension("my_extension", "1.0"); + + // add the example function so that it can be called from PHP scripts + extension.add("run_test", run_test); + + // return the extension details + return extension; + } +}</code></pre> +</p> +<p> + In the example we assigned a C++ lambda function to a Php::Function + object. The Php::Function class is derived from the Php::Value class. + The only difference between a Php::Value and a Php::Function is + that the constructor of Php::Function accepts a function as its + parameter. Despite that difference, both classes are completely + identical. In fact, we would have preferred to make it possible to + assign C++ functions directly to Php::Value objects, but that was + impossible because of calling ambiguities. +</p> +<p> + The Php::Function class can be used as if it is a normal Php::Value + object: you can assign it to other Php::Value objects, and you + can use it as a parameter when you call user space PHP functions. + In the above example we do exactly that: we call the user space + my_iterate() function with our own 'multiply_by_two' C++ function. +</p> |