Writing C code - flaupretre/php-ext-gen GitHub Wiki
Your C code should use the types listed in the 'EG' column below. This is an essential key to extension portability.
PHP | EG | EG macro | PHP 5 | PHP 7 | HHVM |
---|---|---|---|---|---|
bool | eg_bool | EG_BVAL() | long | - | ? |
int | eg_int | EG_IVAL() | long | zend_long | ? |
double | eg_float | EG_FVAL() | double | double | ? |
string pointer | eg_string | EG_STRVAL() | char * | char * | ? |
string size | eg_size | EG_STRLEN() | int | size_t | ? |
array | eg_array | EG_ARRVAL() | HashTable * | HashTable * | ? |
Resource ID | eg_reshandle | EG_RES_HANDLE() | int | int | ? |
Resource type | eg_restype | EG_RES_TYPE() | int | int | ? |
Resource pointer | void * | EG_RES_PTR() | void * | void * | ? |
Resource | eg_resource | - | int | zend_resource * | ? |
There is no restriction on function return value type. The function code can implement its own logic to return any supported value type.
The macros below must be used to define the function's return value. You must execute only one call per function execution. Subsequent calls are ignored.
Macro | Comments |
---|---|
EG_RETVAL_NULL() | Sets null return value |
EG_RETVAL_BOOL(eg_bool) | Sets boolean return value |
EG_RETVAL_FALSE() EG_RETVAL_TRUE() |
Sets true/false as return value |
EG_RETVAL_INT(eg_int) | Sets an integer return value |
EG_RETVAL_FLOAT(eg_float) | Sets a floating-point numeric return value |
EG_RETVAL_STRINGL(eg_string, eg_size, eg_bool dup) | Sets a string return value, providing explicit size. Use this macro if you know the size of your string. For binary strings (which may contain null chars), this macro is the one to use. The resulting string must be stored in dynamically allocated memory. In most cases, setting 'dup' to 1 allocates and copies the string content for you. If string memory is already dynamically allocated and under your control, you can transfer the string with dup=0. In this case, you must not modify anything relative to this pointer later nor free it. Never set a null dup value for string literals ! |
EG_RETVAL_STRING(eg_string, eg_bool dup) | The same as EG_FUNC_RETVAL_STRINGL() but string size is computed using strlen(). Not binary-safe. |
EG_RETVAL_ARRAY(eg_array, eg_bool dup) | Sets an array return value. This array must contain zval elements only As with strings, the array can be duplicated by setting a non-null dup parameter. |
EG_RETVAL_RESOURCE(eg_resource) | Sets a resource return value. res is the result of a previous call to EG_RESOURCE_REGISTER(). |
EG_RETVAL_ZVAL(zval *) | It is also possible to return a zval which won't be modified by the php-ext-gen compatibility layer. This will be used when returning an unsupported type or when an underlying function returns a zval |
Another set of macros exists. Their names are derived from the macros listed above by replacing 'RETVAL' with 'RETURN'. As their name implies, they set the return value, and, then exit from the function.
Defining a argument with a 'zval' type allows user code to manage yet-unsupported types. A 'zval' argument is transmitted and returned (if passed by ref) as-is to/from user code. Every other types are abstracted to an intermediate structure used for input and output.
In the table below, the first column lists every type that can be set in a function's metadata
Type | Supports pass by ref |
Supports default value |
Possible default values |
Built-in default value |
Comments |
---|---|---|---|---|---|
zval | Yes | No | Used to delegate (yet) unsupported type management to user code | ||
bool | Yes | Yes | EG_TRUE/ EG_FALSE |
False | Null is received as 0 |
int | Yes | Yes | Integer | 0 | Null is received as 0 |
float | Yes | Yes | Numeric | 0 | Null is received as 0 |
string | Yes | Yes | String | NULL | |
array | Yes | No | |||
resource | Yes | No | |||
array|null | No | No | |||
array|{bool/int/float/string} | No | Yes | Same as 2nd member | Same as 2nd member | Null is received as 0 |
array|resource | No | No | Any other type is received as an invalid resource |
The function body receives a pointer for each function argument. This pointer has the same name as the name the argument was declared with.
For arguments declared with type 'zval', the argument is a 'zval *'. The user code is totally responsible of the way it uses this zval. If the argument is passed by ref, the user code can change the value of this zval.
For other declared types, the transmitted argument is a pointer to an opaque structure and a set of macros can be used to retrieve the values and, in case of pass-by-ref, to write them back.
In case of mixed types, the 'EG_TYPE(arg)' macro allows to determine the type of the received argument. If argument is not mixed type, you don't have to check the received type.
Example: If argument type is 'array|string', this field can be equal to EG_IS_ARRAY or EG_IS_STRING. Depending on this value, you will use the corresponding macros below.
If type is... | use... | C type | Comments |
---|---|---|---|
Bool | EG_BVAL(arg) | eg_bool | |
Int | EG_IVAL(arg) | eg_int | |
Float | EG_FVAL(arg) | eg_float | |
String | EG_STRVAL(arg) | eg_string | The address of a dynamically-allocated memory buffer containing a null-terminated string argument |
String | EG_STRLEN(arg) | eg_size | String size |
Array | EG_ARRVAL(arg) | eg_array | |
Resource | EG_RES_HANDLE(arg) | eg_reshandle | Resource ID |
Resource | EG_RES_TYPE(arg) | eg_restype | Resource type |
Resource | EG_RES_PTR(arg) | void * |
Resource pointer. If NULL, the received resource is invalid. Must always be checked. |
All | EG_ARG_IS_SET(arg) EG_ARG_IS_UNSET(arg) |
eg_bool | Whether arg was set by caller (can be false on optional arg only). Interesting in case of complex default value. |
To set the returned value of arguments passed by ref, use the macros below.
Notes:
-
the returned value can be any type, whatever type was received.
-
When an argument is passed by value, it is considered read-only, except if optional and not set by the caller. Using one of the macros below on a read-only argument will do nothing.
Macro | Comments |
---|---|
EG_ARG_SET_NULL() | |
EG_ARG_SET_BOOL(eg_bool) | |
EG_ARG_SET_FALSE() EG_RETVAL_TRUE() |
|
EG_ARG_SET_INT(eg_int) | |
EG_ARG_SET_FLOAT(eg_float) | |
EG_ARG_SET_STRINGL(eg_string, eg_size, eg_bool dup) | |
EG_ARG_SET_STRING(eg_string, eg_bool dup) | |
EG_ARG_SET_ARRAY(eg_array, eg_bool dup) | |
EG_ARG_SET_RESOURCE(eg_resource) | Sets a resource return value. res is the result of a previous call to EG_RESOURCE_REGISTER(). |
EG_ARG_SET_ZVAL(zval *) | It is also possible to set a zval which won't be modified by the php-ext-gen compatibility layer. This must be used only when setting a type unsupported by php-ext-gen. |