1--TEST-- 2Feature GH-11934 (Allow to pass CData into struct and/or union fields) 3--EXTENSIONS-- 4ffi 5--INI-- 6ffi.enable=1 7--FILE-- 8<?php 9 10$cdef = FFI::cdef(); 11 12echo "--- Primitive types ---\n"; 13 14// Choose integer numbers off the maximum to test copy 15$types = [ 16 'uint8_t' => 200, 17 'uint16_t' => 16000, 18 'uint32_t' => 1000_000, 19 'uint64_t' => PHP_INT_MAX - 100, 20 'int8_t' => -100, 21 'int16_t' => -16000, 22 'int32_t' => -1000_000, 23 'int64_t' => PHP_INT_MIN + 100, 24 'char' => 'F', 25 'bool' => false, 26 'float' => 1.00, 27 'double' => -1.00, 28]; 29 30// Positive test 31foreach ($types as $type => $value) { 32 $source = $cdef->new($type); 33 $source->cdata = $value; 34 $struct = $cdef->new("struct { $type field; }"); 35 $struct->field = $source; 36 echo "Positive test $type: "; 37 var_dump($struct->field === $value); 38} 39 40// Negative test 41$dummy = $cdef->new("int[2]"); 42foreach ($types as $type => $value) { 43 $struct = $cdef->new("struct { int field; }"); 44 $struct->field = $dummy; 45} 46 47// Enum test 48$enum_definition = "enum { A, B, C, D }"; 49$source = $cdef->new($enum_definition); 50$source->cdata = 2; 51$struct = $cdef->new("struct { $enum_definition field; }"); 52$struct->field = $source; 53echo "Positive test enum: "; 54var_dump($struct->field === $source->cdata); 55$struct->field = $dummy; 56 57echo "--- Struct ---\n"; 58 59// Nested structs 60$cdef = FFI::cdef(" 61 struct inner_struct { 62 int data[1]; 63 }; 64 struct my_struct { 65 int foo; 66 int bar; 67 struct inner_struct inner; 68 }; 69 struct my_nesting_struct { 70 struct my_struct field; 71 };"); 72$source = $cdef->new("struct my_struct"); 73$source->foo = 123; 74$source->bar = 456; 75$source->inner->data[0] = 789; 76$struct = $cdef->new("struct my_nesting_struct"); 77$struct->field = $source; 78var_dump($struct->field->foo === 123 && $struct->field->bar === 456 && $struct->field->inner->data[0] === 789); 79 80echo "--- Callback return type ---\n"; 81 82$ffi = FFI::cdef(' 83typedef uint32_t (*test_callback)(); 84typedef struct { 85 test_callback call_me; 86} my_struct; 87'); 88 89$struct = $ffi->new('my_struct'); 90$struct->call_me = function () use ($ffi) { 91 $int = $ffi->new('uint32_t'); 92 $int->cdata = 42; 93 return $int; 94}; 95 96var_dump(($struct->call_me)()); 97 98echo "--- Other FFI\CData assignment ---\n"; 99 100$ffi = FFI::cdef(''); 101 102$source = $ffi->new('uint32_t'); 103$source->cdata = 123; 104$target = $ffi->new('uint32_t'); 105$target->cdata = $source; 106 107var_dump($target->cdata); 108 109echo "--- Array element ---\n"; 110 111$ffi = FFI::cdef(''); 112 113$source = $ffi->new('uint32_t'); 114$source->cdata = 123; 115$target = $ffi->new('uint32_t[1]'); 116$target[0] = $source; 117 118var_dump($target[0]); 119 120?> 121--EXPECTF-- 122--- Primitive types --- 123Positive test uint8_t: bool(true) 124Positive test uint16_t: bool(true) 125Positive test uint32_t: bool(true) 126Positive test uint64_t: bool(true) 127Positive test int8_t: bool(true) 128Positive test int16_t: bool(true) 129Positive test int32_t: bool(true) 130Positive test int64_t: bool(true) 131Positive test char: bool(true) 132Positive test bool: bool(true) 133Positive test float: bool(true) 134Positive test double: bool(true) 135 136Warning: Object of class FFI\CData could not be converted to int in %s on line %d 137 138Warning: Object of class FFI\CData could not be converted to int in %s on line %d 139 140Warning: Object of class FFI\CData could not be converted to int in %s on line %d 141 142Warning: Object of class FFI\CData could not be converted to int in %s on line %d 143 144Warning: Object of class FFI\CData could not be converted to int in %s on line %d 145 146Warning: Object of class FFI\CData could not be converted to int in %s on line %d 147 148Warning: Object of class FFI\CData could not be converted to int in %s on line %d 149 150Warning: Object of class FFI\CData could not be converted to int in %s on line %d 151 152Warning: Object of class FFI\CData could not be converted to int in %s on line %d 153 154Warning: Object of class FFI\CData could not be converted to int in %s on line %d 155 156Warning: Object of class FFI\CData could not be converted to int in %s on line %d 157 158Warning: Object of class FFI\CData could not be converted to int in %s on line %d 159Positive test enum: bool(true) 160 161Warning: Object of class FFI\CData could not be converted to int in %s on line %d 162--- Struct --- 163bool(true) 164--- Callback return type --- 165int(42) 166--- Other FFI\CData assignment --- 167int(123) 168--- Array element --- 169int(123) 170