@@ -765,6 +765,38 @@ static zend_always_inline int zend_ffi_zval_to_cdata(void *ptr, zend_ffi_type *t
765
765
}
766
766
/* }}} */
767
767
768
+ #if defined(ZEND_WIN32 ) && (defined(HAVE_FFI_FASTCALL ) || defined(HAVE_FFI_STDCALL ))
769
+ static size_t zend_ffi_arg_size (zend_ffi_type * type ) /* {{{ */
770
+ {
771
+ zend_ffi_type * arg_type ;
772
+ size_t arg_size = 0 ;
773
+
774
+ ZEND_HASH_FOREACH_PTR (type -> func .args , arg_type ) {
775
+ arg_size += ZEND_FFI_TYPE (arg_type )-> size ;
776
+ } ZEND_HASH_FOREACH_END ();
777
+ return arg_size ;
778
+ }
779
+ /* }}} */
780
+ #endif
781
+
782
+ static zend_always_inline zend_string * zend_ffi_mangled_func_name (zend_string * name , zend_ffi_type * type ) /* {{{ */
783
+ {
784
+ #ifdef ZEND_WIN32
785
+ switch (type -> func .abi ) {
786
+ # ifdef HAVE_FFI_FASTCALL
787
+ case FFI_FASTCALL :
788
+ return strpprintf (0 , "@%s@%zu" , ZSTR_VAL (name ), zend_ffi_arg_size (type ));
789
+ # endif
790
+ # ifdef HAVE_FFI_STDCALL
791
+ case FFI_STDCALL :
792
+ return strpprintf (0 , "_%s@%zu" , ZSTR_VAL (name ), zend_ffi_arg_size (type ));
793
+ # endif
794
+ }
795
+ #endif
796
+ return zend_string_copy (name );
797
+ }
798
+ /* }}} */
799
+
768
800
#if FFI_CLOSURES
769
801
typedef struct _zend_ffi_callback_data {
770
802
zend_fcall_info_cache fcc ;
@@ -2842,7 +2874,10 @@ ZEND_METHOD(FFI, cdef) /* {{{ */
2842
2874
}
2843
2875
sym -> addr = addr ;
2844
2876
} else if (sym -> kind == ZEND_FFI_SYM_FUNC ) {
2845
- addr = DL_FETCH_SYMBOL (handle , ZSTR_VAL (name ));
2877
+ zend_string * mangled_name = zend_ffi_mangled_func_name (name , ZEND_FFI_TYPE (sym -> type ));
2878
+
2879
+ addr = DL_FETCH_SYMBOL (handle , ZSTR_VAL (mangled_name ));
2880
+ zend_string_release (mangled_name );
2846
2881
if (!addr ) {
2847
2882
zend_throw_error (zend_ffi_exception_ce , "Failed resolving C function '%s'" , ZSTR_VAL (name ));
2848
2883
}
@@ -3172,7 +3207,10 @@ ZEND_METHOD(FFI, load) /* {{{ */
3172
3207
}
3173
3208
sym -> addr = addr ;
3174
3209
} else if (sym -> kind == ZEND_FFI_SYM_FUNC ) {
3175
- addr = DL_FETCH_SYMBOL (handle , ZSTR_VAL (name ));
3210
+ zend_string * mangled_name = zend_ffi_mangled_func_name (name , ZEND_FFI_TYPE (sym -> type ));
3211
+
3212
+ addr = DL_FETCH_SYMBOL (handle , ZSTR_VAL (mangled_name ));
3213
+ zend_string_release (mangled_name );
3176
3214
if (!addr ) {
3177
3215
if (preload ) {
3178
3216
zend_error (E_WARNING , "failed pre-loading '%s', cannot resolve C function '%s'" , filename , ZSTR_VAL (name ));
0 commit comments