1--TEST-- 2GH-16013 (endianness issue with FFI) 3--EXTENSIONS-- 4ffi 5zend_test 6--FILE-- 7<?php 8require_once('utils.inc'); 9 10$header = <<<HEADER 11enum bug_gh16013_enum { 12 BUG_GH16013_A = 1, 13 BUG_GH16013_B = 2, 14}; 15struct bug_gh16013_int_struct { 16 int field; 17}; 18struct bug_gh16013_callback_struct { 19 int8_t (*return_int8)(int8_t); 20 uint8_t (*return_uint8)(uint8_t); 21 int16_t (*return_int16)(int16_t); 22 uint16_t (*return_uint16)(uint16_t); 23 int32_t (*return_int32)(int32_t); 24 uint32_t (*return_uint32)(uint32_t); 25 float (*return_float)(float); 26 struct bug_gh16013_int_struct (*return_struct)(struct bug_gh16013_int_struct); 27 enum bug_gh16013_enum (*return_enum)(enum bug_gh16013_enum); 28}; 29 30char bug_gh16013_return_char(); 31bool bug_gh16013_return_bool(); 32short bug_gh16013_return_short(); 33int bug_gh16013_return_int(); 34enum bug_gh16013_enum bug_gh16013_return_enum(); 35struct bug_gh16013_int_struct bug_gh16013_return_struct(); 36HEADER; 37 38if (PHP_OS_FAMILY !== 'Windows') { 39 $ffi = FFI::cdef($header); 40} else { 41 try { 42 $ffi = FFI::cdef($header, 'php_zend_test.dll'); 43 } catch (FFI\Exception $ex) { 44 $ffi = FFI::cdef($header, ffi_get_php_dll_name()); 45 } 46} 47 48echo "--- Return values ---\n"; 49var_dump($ffi->bug_gh16013_return_char()); 50var_dump($ffi->bug_gh16013_return_bool()); 51var_dump($ffi->bug_gh16013_return_short()); 52var_dump($ffi->bug_gh16013_return_int()); 53var_dump($ffi->bug_gh16013_return_enum()); 54var_dump($ffi->bug_gh16013_return_struct()); 55 56echo "--- Callback values ---\n"; 57$bug_gh16013_callback_struct = $ffi->new('struct bug_gh16013_callback_struct'); 58$bug_gh16013_callback_struct->return_int8 = function($val) use($ffi) { 59 $cdata = $ffi->new('int8_t'); 60 $cdata->cdata = $val; 61 return $cdata; 62}; 63$bug_gh16013_callback_struct->return_uint8 = function($val) use($ffi) { 64 $cdata = $ffi->new('uint8_t'); 65 $cdata->cdata = $val; 66 return $cdata; 67}; 68$bug_gh16013_callback_struct->return_int16 = function($val) use($ffi) { 69 $cdata = $ffi->new('int16_t'); 70 $cdata->cdata = $val; 71 return $cdata; 72}; 73$bug_gh16013_callback_struct->return_uint16 = function($val) use($ffi) { 74 $cdata = $ffi->new('uint16_t'); 75 $cdata->cdata = $val; 76 return $cdata; 77}; 78$bug_gh16013_callback_struct->return_int32 = function($val) use($ffi) { 79 $cdata = $ffi->new('int32_t'); 80 $cdata->cdata = $val; 81 return $cdata; 82}; 83$bug_gh16013_callback_struct->return_uint32 = function($val) use($ffi) { 84 $cdata = $ffi->new('uint32_t'); 85 $cdata->cdata = $val; 86 return $cdata; 87}; 88$bug_gh16013_callback_struct->return_float = function($val) use($ffi) { 89 $cdata = $ffi->new('float'); 90 $cdata->cdata = $val; 91 return $cdata; 92}; 93$bug_gh16013_callback_struct->return_struct = function($val) use($ffi) { 94 return $val; 95}; 96$bug_gh16013_callback_struct->return_enum = function($val) use($ffi) { 97 $cdata = $ffi->new('enum bug_gh16013_enum'); 98 $cdata->cdata = $val; 99 return $cdata; 100}; 101 102var_dump(($bug_gh16013_callback_struct->return_int8)(-4)); 103var_dump(($bug_gh16013_callback_struct->return_uint8)(4)); 104var_dump(($bug_gh16013_callback_struct->return_int16)(-10000)); 105var_dump(($bug_gh16013_callback_struct->return_uint16)(10000)); 106var_dump(($bug_gh16013_callback_struct->return_int32)(-100000)); 107var_dump(($bug_gh16013_callback_struct->return_uint32)(100000)); 108var_dump(($bug_gh16013_callback_struct->return_float)(12.34)); 109$struct = $ffi->new('struct bug_gh16013_int_struct'); 110$struct->field = 10; 111var_dump(($bug_gh16013_callback_struct->return_struct)($struct)); 112var_dump(($bug_gh16013_callback_struct->return_enum)($ffi->BUG_GH16013_B)); 113?> 114--EXPECT-- 115--- Return values --- 116string(1) "A" 117bool(true) 118int(12345) 119int(123456789) 120int(2) 121object(FFI\CData:struct bug_gh16013_int_struct)#2 (1) { 122 ["field"]=> 123 int(123456789) 124} 125--- Callback values --- 126int(-4) 127int(4) 128int(-10000) 129int(10000) 130int(-100000) 131int(100000) 132float(12.34000015258789) 133object(FFI\CData:struct bug_gh16013_int_struct)#13 (1) { 134 ["field"]=> 135 int(10) 136} 137int(2) 138