diff options
author | Lars Kanis <lars@greiz-reinsdorf.de> | 2013-11-10 21:55:25 +0100 |
---|---|---|
committer | Lars Kanis <lars@greiz-reinsdorf.de> | 2013-11-10 21:59:45 +0100 |
commit | 8410d3d1279a72081638a20045d0e38566ad7a8e (patch) | |
tree | 9c2fea908463e50d94d125d492788fc9dca5fd99 | |
parent | 2ae64ccf11a4201ff08d1eb6cfaf9aabdb06580a (diff) | |
download | ffi-8410d3d1279a72081638a20045d0e38566ad7a8e.tar.gz |
Fix compuation of bytes stored on the stack for stdcalls, used for function decoration.
-rw-r--r-- | lib/ffi/library.rb | 8 | ||||
-rw-r--r-- | libtest/FunctionTest.c | 12 | ||||
-rw-r--r-- | spec/ffi/library_spec.rb | 23 |
3 files changed, 39 insertions, 4 deletions
diff --git a/lib/ffi/library.rb b/lib/ffi/library.rb index 6823712..6e231f9 100644 --- a/lib/ffi/library.rb +++ b/lib/ffi/library.rb @@ -279,12 +279,12 @@ module FFI if ffi_convention == :stdcall # Get the size of each parameter size = arg_types.inject(0) do |mem, arg| - mem + arg.size + size = arg.size + # The size must be a multiple of 4 + size += (4 - size) % 4 + mem + size end - # Next, the size must be a multiple of 4 - size += (4 - size) % 4 - result << "_#{name.to_s}@#{size}" # win32 result << "#{name.to_s}@#{size}" # win64 end diff --git a/libtest/FunctionTest.c b/libtest/FunctionTest.c index b4d45bb..eafad89 100644 --- a/libtest/FunctionTest.c +++ b/libtest/FunctionTest.c @@ -56,3 +56,15 @@ void testAsyncCallback(void (*fn)(int), int value) (*fn)(value); #endif } + +#if defined(_WIN32) && !defined(_WIN64) +struct StructUCDP { + unsigned char a1; + double a2; + void *a3; +}; + +void __stdcall testStdcallManyParams(long *a1, char a2, short int a3, int a4, __int64 a5, + struct StructUCDP a6, struct StructUCDP *a7, float a8, double a9) { +} +#endif diff --git a/spec/ffi/library_spec.rb b/spec/ffi/library_spec.rb index d5831a0..eef7f06 100644 --- a/spec/ffi/library_spec.rb +++ b/spec/ffi/library_spec.rb @@ -24,6 +24,29 @@ describe "Library" do end end + if FFI::Platform::OS =~ /windows|cygwin/ && FFI::Platform::ARCH == 'i386' + module LibTestStdcall + extend FFI::Library + ffi_lib TestLibrary::PATH + ffi_convention :stdcall + + class StructUCDP < FFI::Struct + layout :a1, :uchar, + :a2, :double, + :a3, :pointer + end + + attach_function :testStdcallManyParams, [ :pointer, :int8, :int16, :int32, :int64, + StructUCDP.by_value, StructUCDP.by_ref, :float, :double ], :void + end + + it "adds stdcall decoration: testStdcallManyParams@64" do + s = LibTestStdcall::StructUCDP.new + po = FFI::MemoryPointer.new :long + LibTestStdcall.testStdcallManyParams po, 1, 2, 3, 4, s, s, 1.0, 2.0 + end + end + describe "ffi_lib" do it "empty name list should raise error" do lambda { |