summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortduehr <td@matasano.com>2014-07-01 18:25:26 -0500
committertduehr <td@matasano.com>2014-07-01 18:25:26 -0500
commit37ff7139f90ab1fac8cbc1730485cd54054d3c41 (patch)
treebc47a3b398e5bffaaf59a348b26280c6acac28b0
parentf5bfe5cd80a3c7ec46dd034c06e19aeacce31167 (diff)
parent8410d3d1279a72081638a20045d0e38566ad7a8e (diff)
downloadffi-37ff7139f90ab1fac8cbc1730485cd54054d3c41.tar.gz
Merge pull request #307 from larskanis/fix-stdcall-decoration
Fix compuation of bytes stored on the stack for :stdcall, 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 4b50eb3..47a0fa8 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 1f5c65e..9de1684 100644
--- a/spec/ffi/library_spec.rb
+++ b/spec/ffi/library_spec.rb
@@ -26,6 +26,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 {