Writing C code - flaupretre/php-ext-gen GitHub Wiki

Developer's guide [2] - Writing C code

PHP to C type mapping

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 * ?

Function return value

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.

Function arguments

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

Types

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

Accessing argument values

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.

Setting argument return values

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.
⚠️ **GitHub.com Fallback** ⚠️