|
| 1 | +--TEST-- |
| 2 | +FFI 101: PHP symbols (function address) |
| 3 | +--SKIPIF-- |
| 4 | +<?php require_once('skipif.inc'); ?> |
| 5 | +<?php |
| 6 | +try { |
| 7 | + FFI::cdef("extern void *zend_printf;"); |
| 8 | +} catch (Throwable $e) { |
| 9 | + die('skip PHP symbols not available'); |
| 10 | +} |
| 11 | +?> |
| 12 | +--INI-- |
| 13 | +ffi.enable=1 |
| 14 | +--FILE-- |
| 15 | +<?php |
| 16 | +// Check if target supports "fastcall" calling convention |
| 17 | +try { |
| 18 | + FFI::cdef("extern size_t __attribute__((fastcall)) (*zend_printf)(const char *format);"); |
| 19 | + $fastcall = "__attribute__((fastcall)) "; |
| 20 | +} catch (Throwable $e) { |
| 21 | + $fastcall = ""; |
| 22 | +} |
| 23 | +$zend = FFI::cdef(" |
| 24 | + const char *get_zend_version(void); |
| 25 | + //char *get_zend_version(void); |
| 26 | + extern size_t (*zend_printf)(const char *format, ...); |
| 27 | +
|
| 28 | + unsigned long $fastcall zend_hash_func(const char *str, size_t len); |
| 29 | +
|
| 30 | + void $fastcall zend_str_tolower(char *str, size_t length); |
| 31 | +
|
| 32 | +"); |
| 33 | +$f = $zend->get_zend_version; |
| 34 | +var_dump(trim(explode("\n",$f())[0])); |
| 35 | +//var_dump(trim(FFI::string($zend->get_zend_version()))); |
| 36 | +var_dump($zend->zend_printf); |
| 37 | +var_dump(($zend->zend_printf)("Hello %s!\n", "World")); |
| 38 | + |
| 39 | +$f = $zend->zend_hash_func; |
| 40 | +var_dump($f("file", strlen("file"))); |
| 41 | + |
| 42 | +$str = $zend->new("char[16]"); |
| 43 | +FFI::memcpy($str, "Hello World!", strlen("Hello World!")); |
| 44 | +$f = $zend->zend_str_tolower; |
| 45 | +$f($str, strlen("Hello World!")); |
| 46 | +var_dump(FFI::string($str)); |
| 47 | + |
| 48 | +?> |
| 49 | +--EXPECTF-- |
| 50 | +string(%d) "Zend Engine %s" |
| 51 | +object(FFI\CData:uint%d_t(*)())#%d (1) { |
| 52 | + [0]=> |
| 53 | + object(FFI\CData:uint%d_t())#%d (0) { |
| 54 | + } |
| 55 | +} |
| 56 | +Hello World! |
| 57 | +int(13) |
| 58 | +int(%i) |
| 59 | +string(12) "hello world!" |
0 commit comments