diff --git a/.github/workflows/win.yml b/.github/workflows/win.yml
index c2016ce612fa..133a469034ef 100644
--- a/.github/workflows/win.yml
+++ b/.github/workflows/win.yml
@@ -44,6 +44,7 @@ jobs:
libs/pcre.lib
libs/iconv.lib
libs/gc.lib
+ libs/ffi.lib
libs/z.lib
libs/mpir.lib
libs/yaml.lib
@@ -110,6 +111,37 @@ jobs:
' > 'Override.props'
MSBuild.exe /p:Platform=x64 /p:Configuration=ReleaseStatic libiconv.vcxproj
+ - name: Download libffi
+ if: steps.cache-libs.outputs.cache-hit != 'true'
+ uses: actions/checkout@v2
+ with:
+ repository: winlibs/libffi
+ ref: libffi-3.3
+ path: libffi
+ - name: Build libffi
+ if: steps.cache-libs.outputs.cache-hit != 'true'
+ working-directory: ./libffi
+ run: |
+ echo '
+
+ $(MsbuildThisFileDirectory)\Override.props
+
+ ' > 'Directory.Build.props'
+
+ echo '
+
+
+ MultiThreaded
+ None
+ false
+
+
+ false
+
+
+ ' > 'Override.props'
+
+ MSBuild.exe /p:PlatformToolset=v143 /p:Platform=x64 /p:Configuration=Release win32\vs16_x64\libffi-msvc.sln -target:libffi:Rebuild
- name: Download zlib
if: steps.cache-libs.outputs.cache-hit != 'true'
run: |
@@ -200,6 +232,7 @@ jobs:
mv pcre/Release/pcre.lib libs/
mv libiconv/lib64/libiconvStatic.lib libs/iconv.lib
mv bdwgc/Release/gc.lib libs/
+ mv libffi/win32/vs16_x64/x64/Release/libffi.lib libs/ffi.lib
mv zlib/Release/zlibstatic.lib libs/z.lib
mv mpir/lib/x64/Release/mpir.lib libs/
mv libyaml/Release/yaml.lib libs/
diff --git a/spec/compiler/ffi/ffi_spec.cr b/spec/compiler/ffi/ffi_spec.cr
index 4b70658e6bb8..5bf1b3cc97f2 100644
--- a/spec/compiler/ffi/ffi_spec.cr
+++ b/spec/compiler/ffi/ffi_spec.cr
@@ -1,4 +1,5 @@
-{% skip_file if !flag?(:unix) || flag?(:without_ffi) || flag?(:wasm32) %}
+{% skip_file if flag?(:without_ffi) || flag?(:wasm32) %}
+{% skip_file unless flag?(:unix) || flag?(:win32) %}
require "../spec_helper"
require "compiler/crystal/ffi"
@@ -167,34 +168,37 @@ describe Crystal::FFI::CallInterface do
loader.try &.close_all
end
- it "array" do
- call_interface = Crystal::FFI::CallInterface.new Crystal::FFI::Type.sint32, [
- Crystal::FFI::Type.struct([
- Crystal::FFI::Type.sint32,
- Crystal::FFI::Type.sint32,
- Crystal::FFI::Type.sint32,
- Crystal::FFI::Type.sint32,
- ]),
- ] of Crystal::FFI::Type
-
- loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH])
- loader.load_library "sum"
- function_pointer = loader.find_symbol("sum_array")
-
- return_value = 0_i32
-
- ary = [1, 2, 3, 4]
-
- arg_pointers = StaticArray[
- Pointer.malloc(1, ary.to_unsafe).as(Void*),
- Pointer(Void).null,
- ]
-
- call_interface.call(function_pointer, arg_pointers.to_unsafe, pointerof(return_value).as(Void*))
- return_value.should eq 10
- ensure
- loader.try &.close_all
- end
+ # passing C array by value is not supported everywhere
+ {% unless flag?(:win32) %}
+ it "array" do
+ call_interface = Crystal::FFI::CallInterface.new Crystal::FFI::Type.sint32, [
+ Crystal::FFI::Type.struct([
+ Crystal::FFI::Type.sint32,
+ Crystal::FFI::Type.sint32,
+ Crystal::FFI::Type.sint32,
+ Crystal::FFI::Type.sint32,
+ ]),
+ ] of Crystal::FFI::Type
+
+ loader = Crystal::Loader.new([SPEC_CRYSTAL_LOADER_LIB_PATH])
+ loader.load_library "sum"
+ function_pointer = loader.find_symbol("sum_array")
+
+ return_value = 0_i32
+
+ ary = [1, 2, 3, 4]
+
+ arg_pointers = StaticArray[
+ Pointer.malloc(1, ary.to_unsafe).as(Void*),
+ Pointer(Void).null,
+ ]
+
+ call_interface.call(function_pointer, arg_pointers.to_unsafe, pointerof(return_value).as(Void*))
+ return_value.should eq 10
+ ensure
+ loader.try &.close_all
+ end
+ {% end %}
end
describe ".variadic" do