summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLars Kanis <lars@greiz-reinsdorf.de>2013-11-10 21:55:25 +0100
committerLars Kanis <lars@greiz-reinsdorf.de>2013-11-10 21:59:45 +0100
commit8410d3d1279a72081638a20045d0e38566ad7a8e (patch)
tree9c2fea908463e50d94d125d492788fc9dca5fd99
parent2ae64ccf11a4201ff08d1eb6cfaf9aabdb06580a (diff)
downloadffi-8410d3d1279a72081638a20045d0e38566ad7a8e.tar.gz
Fix compuation of bytes stored on the stack for stdcalls, used for function decoration.
-rw-r--r--lib/ffi/library.rb8
-rw-r--r--libtest/FunctionTest.c12
-rw-r--r--spec/ffi/library_spec.rb23
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 {