ffi 1.10.0-x64-mingw32 → 1.11.0-x64-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f00595ece199de615280147c74f408f6af8e264958100b64aba412d0344f6ba1
4
- data.tar.gz: 70490685784dc3c09f7fac286ce35593aae862f689eb2162e6aaaf55fb001ab3
3
+ metadata.gz: b200fd392bc9f98ae4cec9e7034d6632a8959cc40252e01510473744b47e1335
4
+ data.tar.gz: 03b653aae4bfea89deb7e4d191cbde093f19b600424f4594a3d81872a1efae8a
5
5
  SHA512:
6
- metadata.gz: 14cd59477c9ba966e1dad234ea783007b4caccb9b68cd9711ee0f9d0fdc3839cb3874346d32dd0a04100a4eeaab6ff7c33198f0e65ea08ab9be488c206669b51
7
- data.tar.gz: 93f90b44bf4d300c9243cf5eada503aafd77e809d47b1247d1e43dff47294c09ce98ae8fe47c5933e08686b4bce15e04327869b654e861fcd71cc6b64f4073f0
6
+ metadata.gz: 9ebbe34ff72f457b8d4bec3c9acec4a4fef432974f1c49cdf868e886035ffbbceca7705d04c584a940a169de984c940a851ab01934b8c78f3b7648d4bd84448f
7
+ data.tar.gz: 652ab0c9dec4c3fde7a6e004d2fa2b835e20bbb7dd67f010b234eda189ea6d423f72c5368703a05eeeb6bf6c4ddde42549cf3f6f5718e8ab045518649fc357bb
data/.gitignore CHANGED
@@ -20,3 +20,6 @@ vendor
20
20
  Gemfile.lock
21
21
  types_log
22
22
  *.gem
23
+ embed-test.log
24
+ spec/ffi/embed-test/ext/Makefile
25
+ spec/ffi/embed-test/ext/embed_test.bundle
@@ -1,3 +1,4 @@
1
1
  [submodule "ext/ffi_c/libffi"]
2
2
  path = ext/ffi_c/libffi
3
- url = https://github.com/libffi/libffi.git
3
+ url = https://github.com/larskanis/libffi.git
4
+ branch = fix-stdcall
@@ -1,12 +1,11 @@
1
1
  dist: trusty
2
- sudo: false
3
2
  group: beta
4
3
  language: ruby
5
- before_install:
6
- - gem install bundler
4
+
7
5
  script:
8
6
  - bundle exec rake compile || bundle exec rake compile
9
7
  - bundle exec rake test
8
+ - ITER=10 bundle exec rake bench:all
10
9
  os:
11
10
  - linux
12
11
  - osx
@@ -16,28 +15,28 @@ rvm:
16
15
  - 2.5.3
17
16
  - 2.6.0
18
17
  - ruby-head
19
- - system
18
+
20
19
  env:
21
20
  - CC=gcc
22
21
  - CC=clang
23
22
  matrix:
24
23
  allow_failures:
25
- - rvm: system
26
24
  - os: osx
27
25
  rvm: ruby-head
28
- exclude: # ruby 2.4.2 needs build with xcode9 or later on osx
29
- - os: osx
30
- rvm: 2.4.2
31
26
  include:
32
- - os: osx
33
- osx_image: xcode9.1
34
- rvm: 2.4.2
35
- env:
36
- - CC=gcc
37
- - os: osx
38
- osx_image: xcode9.1
39
- rvm: 2.4.2
40
- env:
41
- - CC=clang
27
+ - name: powerpc
28
+ language: generic
29
+ before_install: |
30
+ docker run --rm --privileged multiarch/qemu-user-static:register --reset &&
31
+ docker build --rm -t ffi-powerpc -f spec/env/Dockerfile.powerpc .
32
+ script: |
33
+ docker run --rm -t -v `pwd`:/ffi ffi-powerpc
34
+ - name: armhf
35
+ language: generic
36
+ before_install: |
37
+ docker run --rm --privileged multiarch/qemu-user-static:register --reset &&
38
+ docker build --rm -t ffi-armhf -f spec/env/Dockerfile.armhf .
39
+ script: |
40
+ docker run --rm -t -v `pwd`:/ffi ffi-armhf
42
41
  after_failure:
43
42
  - "find build -name mkmf.log | xargs cat"
@@ -1,3 +1,24 @@
1
+ 1.11.0 / 2019-05-17
2
+ -------------------
3
+
4
+ Added:
5
+ * Add proper documentation to FFI::Generator and ::Task
6
+ * Add gemspec metadata. #696, #698
7
+
8
+ Changed:
9
+ * Add ability to disable or force system libffi. #669
10
+ Use like `gem inst ffi -- --enable-system-libffi` .
11
+ * Move FFI::Platform::CPU from C to Ruby. #663
12
+ * Fix stdcall on Win32. #649, #669
13
+ * Move FFI::StructByReference to Ruby. #681
14
+ * Fix FFI::Pointer#read_string(0) to return a binary String. #692
15
+ * Fix load paths for FFI::Generator::Task
16
+
17
+ Removed:
18
+ * Remove ruby-1.8 and 1.9 compatibility code. #683
19
+ * Remove unused spec files. #684
20
+
21
+
1
22
  1.10.0 / 2019-01-06
2
23
  -------------------
3
24
 
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  group :development do
4
- gem 'rake', '~> 10.1'
4
+ gem 'rake', '~> 12.1'
5
5
  gem 'rake-compiler', '~> 1.0.3'
6
6
  gem 'rake-compiler-dock', '~> 0.7.0'
7
7
  gem 'rspec', '~> 3.0'
data/README.md CHANGED
@@ -1,19 +1,19 @@
1
- # ruby-ffi https://wiki.github.com/ffi/ffi [![Build Status](https://travis-ci.org/ffi/ffi.png?branch=master)](https://travis-ci.org/ffi/ffi) [![Build status Windows](https://ci.appveyor.com/api/projects/status/r8wxn1sd4s794gg1/branch/master?svg=true)](https://ci.appveyor.com/project/larskanis/ffi-aofqa/branch/master)
1
+ # Ruby-FFI https://github.com/ffi/ffi/wiki [![Build Status](https://travis-ci.org/ffi/ffi.svg?branch=master)](https://travis-ci.org/ffi/ffi) [![Build status Windows](https://ci.appveyor.com/api/projects/status/r8wxn1sd4s794gg1/branch/master?svg=true)](https://ci.appveyor.com/project/larskanis/ffi-aofqa/branch/master)
2
2
 
3
3
  ## Description
4
4
 
5
- Ruby-FFI is a ruby extension for programmatically loading dynamic
5
+ Ruby-FFI is a gem for programmatically loading dynamically-linked native
6
6
  libraries, binding functions within them, and calling those functions
7
7
  from Ruby code. Moreover, a Ruby-FFI extension works without changes
8
- on Ruby and JRuby. [Discover why you should write your next extension
9
- using Ruby-FFI](https://wiki.github.com/ffi/ffi/why-use-ffi).
8
+ on CRuby (MRI), JRuby, Rubinius and TruffleRuby. [Discover why you should write your next extension
9
+ using Ruby-FFI](https://github.com/ffi/ffi/wiki/why-use-ffi).
10
10
 
11
- ## Features/problems
11
+ ## Features
12
12
 
13
13
  * Intuitive DSL
14
14
  * Supports all C native types
15
15
  * C structs (also nested), enums and global variables
16
- * Callbacks from C to ruby
16
+ * Callbacks from C to Ruby
17
17
  * Automatic garbage collection of native memory
18
18
 
19
19
  ## Synopsis
@@ -30,20 +30,23 @@ end
30
30
  MyLib.puts 'Hello, World using libc!'
31
31
  ```
32
32
 
33
- For less minimalistic and more sane examples you may look at:
33
+ For less minimalistic and more examples you may look at:
34
34
 
35
- * the samples/ folder
36
- * the examples on the [wiki](https://wiki.github.com/ffi/ffi)
37
- * the projects using FFI listed on this page (https://wiki.github.com/ffi/ffi/projects-using-ffi)
35
+ * the `samples/` folder
36
+ * the examples on the [wiki](https://github.com/ffi/ffi/wiki)
37
+ * the projects using FFI listed on the wiki: https://github.com/ffi/ffi/wiki/projects-using-ffi
38
38
 
39
39
  ## Requirements
40
40
 
41
- You need a sane building environment in order to compile the extension.
42
- At a minimum, you will need:
43
- * A C compiler (e.g. Xcode on OSX, gcc on everything else)
44
- * libffi development library - this is commonly in the libffi-dev or libffi-devel
41
+ When installing the gem on CRuby (MRI) or Rubinius, you will need:
42
+ * A C compiler (e.g., Xcode on macOS, `gcc` or `clang` on everything else)
43
+ * The `libffi` library and development headers - this is commonly in the `libffi-dev` or `libffi-devel` packages
45
44
 
46
- On Linux systems running with [PaX](https://en.wikipedia.org/wiki/PaX) (Gentoo, Alpine, etc.) FFI may trigger `mprotect` errors. You may need to disable [mprotect](https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Restrict_mprotect.28.29) for ruby (`paxctl -m [/path/to/ruby]`) for the time being until a solution is found.
45
+ On Linux systems running with [PaX](https://en.wikipedia.org/wiki/PaX) (Gentoo, Alpine, etc.), FFI may trigger `mprotect` errors. You may need to disable [mprotect](https://en.wikibooks.org/wiki/Grsecurity/Appendix/Grsecurity_and_PaX_Configuration_Options#Restrict_mprotect.28.29) for ruby (`paxctl -m [/path/to/ruby]`) for the time being until a solution is found.
46
+
47
+ On FreeBSD systems pkgconf must be installed for the gem to be able to compile using clang. Install either via packages `pkg install pkgconf` or from ports via `devel/pkgconf`.
48
+
49
+ On JRuby and TruffleRuby, there are no requirements to install the FFI gem, and `require 'ffi'` works even without installing the gem (i.e., the gem is preinstalled on these implementations).
47
50
 
48
51
  ## Installation
49
52
 
@@ -61,8 +64,7 @@ or from the git repository on github:
61
64
  ## License
62
65
 
63
66
  The ffi library is covered by the BSD license, also see the LICENSE file.
64
- The specs are shared with Rubyspec and are licensed by the same license
65
- as Rubyspec, see the LICENSE.SPECS file.
67
+ The specs are covered by the same license as [ruby/spec](https://github.com/ruby/spec), the MIT license.
66
68
 
67
69
  ## Credits
68
70
 
@@ -74,6 +76,7 @@ The following people have submitted code, bug reports, or otherwise contributed
74
76
  * Andreas Niederl <rico32@gmx.net>
75
77
  * Andrew Cholakian <andrew@andrewvc.com>
76
78
  * Antonio Terceiro <terceiro@softwarelivre.org>
79
+ * Benoit Daloze <eregontp@gmail.com>
77
80
  * Brian Candler <B.Candler@pobox.com>
78
81
  * Brian D. Burns <burns180@gmail.com>
79
82
  * Bryan Kearney <bkearney@redhat.com>
data/Rakefile CHANGED
@@ -3,82 +3,16 @@ require 'rbconfig'
3
3
  require 'rake/clean'
4
4
  require File.expand_path("./lib/ffi/version")
5
5
 
6
- USE_RAKE_COMPILER = (RUBY_PLATFORM =~ /java/) ? false : true
7
- if USE_RAKE_COMPILER
8
- require 'rake/extensiontask'
9
- end
10
-
11
6
  require 'date'
12
7
  require 'fileutils'
13
8
  require 'rbconfig'
14
9
  require 'rspec/core/rake_task'
15
10
  require 'rubygems/package_task'
16
11
 
17
- LIBEXT = case RbConfig::CONFIG['host_os'].downcase
18
- when /darwin/
19
- "dylib"
20
- when /mswin|mingw/
21
- "dll"
22
- else
23
- RbConfig::CONFIG['DLEXT']
24
- end
25
-
26
- CPU = case RbConfig::CONFIG['host_cpu'].downcase
27
- when /i[3456]86/
28
- # Darwin always reports i686, even when running in 64bit mode
29
- if RbConfig::CONFIG['host_os'] =~ /darwin/ && 0xfee1deadbeef.is_a?(Fixnum)
30
- "x86_64"
31
- else
32
- "i386"
33
- end
34
-
35
- when /amd64|x86_64/
36
- "x86_64"
37
-
38
- when /ppc64|powerpc64/
39
- "powerpc64"
40
-
41
- when /ppc|powerpc/
42
- "powerpc"
43
-
44
- when /^arm/
45
- "arm"
46
-
47
- else
48
- RbConfig::CONFIG['host_cpu']
49
- end
50
-
51
- OS = case RbConfig::CONFIG['host_os'].downcase
52
- when /linux/
53
- "linux"
54
- when /darwin/
55
- "darwin"
56
- when /freebsd/
57
- "freebsd"
58
- when /openbsd/
59
- "openbsd"
60
- when /sunos|solaris/
61
- "solaris"
62
- when /mswin|mingw/
63
- "win32"
64
- else
65
- RbConfig::CONFIG['host_os'].downcase
66
- end
67
-
68
- def which(name)
69
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
70
- ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
71
- exts.each do |ext|
72
- app = File.join(path, name+ext)
73
- return app if File.executable? app
74
- end
75
- end
76
- nil
12
+ def java?
13
+ /java/ === RUBY_PLATFORM
77
14
  end
78
15
 
79
- GMAKE = which('gmake').nil? ? 'make' : 'gmake'
80
-
81
- LIBTEST = "build/libtest.#{LIBEXT}"
82
16
  BUILD_DIR = "build"
83
17
  BUILD_EXT_DIR = File.join(BUILD_DIR, "#{RbConfig::CONFIG['arch']}", 'ffi_c', RUBY_VERSION)
84
18
 
@@ -86,7 +20,7 @@ def gem_spec
86
20
  @gem_spec ||= Gem::Specification.load('ffi.gemspec')
87
21
  end
88
22
 
89
- TEST_DEPS = [ LIBTEST ]
23
+ TEST_DEPS = []
90
24
  if RUBY_PLATFORM == "java"
91
25
  RSpec::Core::RakeTask.new(:spec) do |config|
92
26
  config.rspec_opts = YAML.load_file 'spec/spec.opts'
@@ -110,30 +44,22 @@ CLEAN.include 'build'
110
44
  CLEAN.include 'conftest.dSYM'
111
45
  CLEAN.include 'spec/ffi/fixtures/libtest.{dylib,so,dll}'
112
46
  CLEAN.include 'spec/ffi/fixtures/*.o'
47
+ CLEAN.include 'spec/ffi/embed-test/ext/*.{o,def}'
48
+ CLEAN.include 'spec/ffi/embed-test/ext/Makefile'
113
49
  CLEAN.include "pkg/ffi-*-{mingw32,java}"
114
50
  CLEAN.include 'lib/1.*'
115
51
  CLEAN.include 'lib/2.*'
116
- CLEAN.include 'bin'
117
52
 
118
53
  task :distclean => :clobber
119
54
 
120
- desc "Build the native test lib"
121
- file "build/libtest.#{LIBEXT}" => FileList['libtest/**/*.[ch]'] do
122
- sh %{#{GMAKE} -f libtest/GNUmakefile CPU=#{CPU} OS=#{OS} }
123
- end
124
-
125
-
126
- desc "Build test helper lib"
127
- task :libtest => "build/libtest.#{LIBEXT}"
128
-
129
55
  desc "Test the extension"
130
56
  task :test => [ :spec ]
131
57
 
132
58
 
133
59
  namespace :bench do
134
60
  ITER = ENV['ITER'] ? ENV['ITER'].to_i : 100000
135
- bench_libs = "-Ilib -I#{BUILD_DIR}" unless RUBY_PLATFORM == "java"
136
- bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench_helper.rb" }
61
+ bench_libs = "-Ilib" unless RUBY_PLATFORM == "java"
62
+ bench_files = Dir["bench/bench_*.rb"].reject { |f| f == "bench/bench_helper.rb" }
137
63
  bench_files.each do |bench|
138
64
  task File.basename(bench, ".rb")[6..-1] => TEST_DEPS do
139
65
  sh %{#{Gem.ruby} #{bench_libs} #{bench} #{ITER}}
@@ -175,8 +101,8 @@ end
175
101
 
176
102
  task 'gem:java' => 'java:gem'
177
103
 
178
-
179
- if USE_RAKE_COMPILER
104
+ unless java?
105
+ require 'rake/extensiontask'
180
106
  Rake::ExtensionTask.new('ffi_c', gem_spec) do |ext|
181
107
  ext.name = 'ffi_c' # indicate the name of the extension.
182
108
  # ext.lib_dir = BUILD_DIR # put binaries into this folder.
@@ -212,6 +138,7 @@ file "ext/ffi_c/libffi/autogen.sh" => "ext/ffi_c/libffi" do
212
138
  warn "Downloading libffi ..."
213
139
  sh "git submodule update --init --recursive"
214
140
  end
141
+ task :libffi => "ext/ffi_c/libffi/autogen.sh"
215
142
 
216
143
  LIBFFI_GIT_FILES = `git --git-dir ext/ffi_c/libffi/.git ls-files -z`.split("\x0")
217
144
 
@@ -12,11 +12,16 @@ install:
12
12
  - bundle install
13
13
  build: off
14
14
  build_script:
15
- - bundle exec rake compile || bundle exec rake compile
15
+ - bundle exec rake libffi compile -- %EXTCONFOPTS% || bundle exec rake compile -- %EXTCONFOPTS%
16
16
  test_script:
17
17
  - bundle exec rake test
18
18
  environment:
19
19
  matrix:
20
20
  - RUBYVER: "head-x64"
21
+ EXTCONFOPTS: "--disable-system-libffi"
21
22
  - RUBYVER: 24
23
+ EXTCONFOPTS: "--disable-system-libffi"
22
24
  - RUBYVER: 25-x64
25
+ EXTCONFOPTS: "--enable-system-libffi"
26
+ - RUBYVER: 25
27
+ EXTCONFOPTS: "--enable-system-libffi"
@@ -8,6 +8,14 @@ Gem::Specification.new do |s|
8
8
  s.homepage = 'http://wiki.github.com/ffi/ffi'
9
9
  s.summary = 'Ruby FFI'
10
10
  s.description = 'Ruby FFI library'
11
+ if s.respond_to?(:metadata)
12
+ s.metadata['bug_tracker_uri'] = 'https://github.com/ffi/ffi/issues'
13
+ s.metadata['changelog_uri'] = 'https://github.com/ffi/ffi/blob/master/CHANGELOG.md'
14
+ s.metadata['documentation_uri'] = 'https://github.com/ffi/ffi/wiki'
15
+ s.metadata['wiki_uri'] = 'https://github.com/ffi/ffi/wiki'
16
+ s.metadata['source_code_uri'] = 'https://github.com/ffi/ffi/'
17
+ s.metadata['mailing_list_uri'] = 'http://groups.google.com/group/ruby-ffi'
18
+ end
11
19
  s.files = `git ls-files -z`.split("\x0").reject do |f|
12
20
  f =~ /^(bench|gen|libtest|nbproject|spec)/
13
21
  end
@@ -23,14 +31,13 @@ Gem::Specification.new do |s|
23
31
  end
24
32
 
25
33
  s.extensions << 'ext/ffi_c/extconf.rb'
26
- s.has_rdoc = false
27
34
  s.rdoc_options = %w[--exclude=ext/ffi_c/.*\.o$ --exclude=ffi_c\.(bundle|so)$]
28
35
  s.license = 'BSD-3-Clause'
29
36
  s.require_paths << 'ext/ffi_c'
30
37
  s.required_ruby_version = '>= 1.9'
31
- s.add_development_dependency 'rake', '~> 10.1'
38
+ s.add_development_dependency 'rake', '~> 12.1'
32
39
  s.add_development_dependency 'rake-compiler', '~> 1.0'
33
- s.add_development_dependency 'rake-compiler-dock', '~> 0.6.2'
40
+ s.add_development_dependency 'rake-compiler-dock', '~> 0.7.0'
34
41
  s.add_development_dependency 'rspec', '~> 2.14.1'
35
42
  s.add_development_dependency 'rubygems-tasks', "~> 0.2.4"
36
43
  end
@@ -0,0 +1,67 @@
1
+ #
2
+ # Copyright (C) 2008-2010 Wayne Meissner
3
+ #
4
+ # This file is part of ruby-ffi.
5
+ #
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # * Redistributions of source code must retain the above copyright notice, this
12
+ # list of conditions and the following disclaimer.
13
+ # * Redistributions in binary form must reproduce the above copyright notice
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
17
+ # may be used to endorse or promote products derived from this software
18
+ # without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
30
+
31
+ module FFI
32
+ # This module is used to extend somes classes and give then a common API.
33
+ #
34
+ # Most of methods defined here must be overriden.
35
+ module DataConverter
36
+ # Get native type.
37
+ #
38
+ # @overload native_type(type)
39
+ # @param [String, Symbol, Type] type
40
+ # @return [Type]
41
+ # Get native type from +type+.
42
+ #
43
+ # @overload native_type
44
+ # @raise {NotImplementedError} This method must be overriden.
45
+ def native_type(type = nil)
46
+ if type
47
+ @native_type = FFI.find_type(type)
48
+ else
49
+ native_type = @native_type
50
+ unless native_type
51
+ raise NotImplementedError, 'native_type method not overridden and no native_type set'
52
+ end
53
+ native_type
54
+ end
55
+ end
56
+
57
+ # Convert to a native type.
58
+ def to_native(value, ctx)
59
+ value
60
+ end
61
+
62
+ # Convert from a native type.
63
+ def from_native(value, ctx)
64
+ value
65
+ end
66
+ end
67
+ end
@@ -29,6 +29,7 @@
29
29
  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
30
 
31
31
  require 'ffi/platform'
32
+ require 'ffi/data_converter'
32
33
  require 'ffi/types'
33
34
  require 'ffi/library'
34
35
  require 'ffi/errno'
@@ -56,6 +56,8 @@ module FFI
56
56
 
57
57
  OSVERSION = RbConfig::CONFIG['host_os'].gsub(/[^\d]/, '').to_i
58
58
 
59
+ CPU = RbConfig::CONFIG['host_cpu']
60
+
59
61
  ARCH = case CPU.downcase
60
62
  when /amd64|x86_64/
61
63
  "x86_64"
@@ -49,7 +49,7 @@ module FFI
49
49
  # equivalent string if +len+ is not +nil+.
50
50
  def read_string(len=nil)
51
51
  if len
52
- return '' if len == 0
52
+ return ''.b if len == 0
53
53
  get_bytes(0, len)
54
54
  else
55
55
  get_string(0)
@@ -32,72 +32,12 @@
32
32
  #
33
33
 
34
34
  require 'ffi/platform'
35
+ require 'ffi/struct_layout'
35
36
  require 'ffi/struct_layout_builder'
37
+ require 'ffi/struct_by_reference'
36
38
 
37
39
  module FFI
38
40
 
39
- class StructLayout
40
-
41
- # @return [Array<Array(Symbol, Numeric)>
42
- # Get an array of tuples (field name, offset of the field).
43
- def offsets
44
- members.map { |m| [ m, self[m].offset ] }
45
- end
46
-
47
- # @return [Numeric]
48
- # Get the offset of a field.
49
- def offset_of(field_name)
50
- self[field_name].offset
51
- end
52
-
53
- # An enum {Field} in a {StructLayout}.
54
- class Enum < Field
55
-
56
- # @param [AbstractMemory] ptr pointer on a {Struct}
57
- # @return [Object]
58
- # Get an object of type {#type} from memory pointed by +ptr+.
59
- def get(ptr)
60
- type.find(ptr.get_int(offset))
61
- end
62
-
63
- # @param [AbstractMemory] ptr pointer on a {Struct}
64
- # @param value
65
- # @return [nil]
66
- # Set +value+ into memory pointed by +ptr+.
67
- def put(ptr, value)
68
- ptr.put_int(offset, type.find(value))
69
- end
70
-
71
- end
72
-
73
- class InnerStruct < Field
74
- def get(ptr)
75
- type.struct_class.new(ptr.slice(self.offset, self.size))
76
- end
77
-
78
- def put(ptr, value)
79
- raise TypeError, "wrong value type (expected #{type.struct_class})" unless value.is_a?(type.struct_class)
80
- ptr.slice(self.offset, self.size).__copy_from__(value.pointer, self.size)
81
- end
82
- end
83
-
84
- class Mapped < Field
85
- def initialize(name, offset, type, orig_field)
86
- super(name, offset, type)
87
- @orig_field = orig_field
88
- end
89
-
90
- def get(ptr)
91
- type.from_native(@orig_field.get(ptr), nil)
92
- end
93
-
94
- def put(ptr, value)
95
- @orig_field.put(ptr, type.to_native(value, nil))
96
- end
97
- end
98
- end
99
-
100
-
101
41
  class Struct
102
42
 
103
43
  # Get struct size
@@ -296,7 +236,7 @@ module FFI
296
236
  @packed = packed
297
237
  end
298
238
  alias :pack :packed
299
-
239
+
300
240
  def aligned(alignment = 1)
301
241
  @min_alignment = alignment
302
242
  end
@@ -0,0 +1,72 @@
1
+ #
2
+ # Copyright (C) 2010 Wayne Meissner
3
+ #
4
+ # This file is part of ruby-ffi.
5
+ #
6
+ # All rights reserved.
7
+ #
8
+ # Redistribution and use in source and binary forms, with or without
9
+ # modification, are permitted provided that the following conditions are met:
10
+ #
11
+ # * Redistributions of source code must retain the above copyright notice, this
12
+ # list of conditions and the following disclaimer.
13
+ # * Redistributions in binary form must reproduce the above copyright notice
14
+ # this list of conditions and the following disclaimer in the documentation
15
+ # and/or other materials provided with the distribution.
16
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
17
+ # may be used to endorse or promote products derived from this software
18
+ # without specific prior written permission.
19
+ #
20
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
24
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.#
30
+
31
+ module FFI
32
+ # This class includes the {FFI::DataConverter} module.
33
+ class StructByReference
34
+ include DataConverter
35
+
36
+ attr_reader :struct_class
37
+
38
+ # @param [Struct] struct_class
39
+ def initialize(struct_class)
40
+ unless Class === struct_class and struct_class < FFI::Struct
41
+ raise TypeError, 'wrong type (expected subclass of FFI::Struct)'
42
+ end
43
+ @struct_class = struct_class
44
+ end
45
+
46
+ # Always get {FFI::Type}::POINTER.
47
+ def native_type
48
+ FFI::Type::POINTER
49
+ end
50
+
51
+ # @param [nil, Struct] value
52
+ # @param [nil] ctx
53
+ # @return [AbstractMemory] Pointer on +value+.
54
+ def to_native(value, ctx)
55
+ return Pointer::NULL if value.nil?
56
+
57
+ unless @struct_class === value
58
+ raise TypeError, "wrong argument type #{value.class} (expected #{@struct_class})"
59
+ end
60
+
61
+ value.pointer
62
+ end
63
+
64
+ # @param [AbstractMemory] value
65
+ # @param [nil] ctx
66
+ # @return [Struct]
67
+ # Create a struct from content of memory +value+.
68
+ def from_native(value, ctx)
69
+ @struct_class.new(value)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,96 @@
1
+ #
2
+ # Copyright (C) 2008-2010 Wayne Meissner
3
+ # Copyright (C) 2008, 2009 Andrea Fazzi
4
+ # Copyright (C) 2008, 2009 Luc Heinrich
5
+ #
6
+ # This file is part of ruby-ffi.
7
+ #
8
+ # All rights reserved.
9
+ #
10
+ # Redistribution and use in source and binary forms, with or without
11
+ # modification, are permitted provided that the following conditions are met:
12
+ #
13
+ # * Redistributions of source code must retain the above copyright notice, this
14
+ # list of conditions and the following disclaimer.
15
+ # * Redistributions in binary form must reproduce the above copyright notice
16
+ # this list of conditions and the following disclaimer in the documentation
17
+ # and/or other materials provided with the distribution.
18
+ # * Neither the name of the Ruby FFI project nor the names of its contributors
19
+ # may be used to endorse or promote products derived from this software
20
+ # without specific prior written permission.
21
+ #
22
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23
+ # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
+ # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
25
+ # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
26
+ # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
+ # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
28
+ # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29
+ # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30
+ # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
+ #
33
+
34
+ module FFI
35
+
36
+ class StructLayout
37
+
38
+ # @return [Array<Array(Symbol, Numeric)>
39
+ # Get an array of tuples (field name, offset of the field).
40
+ def offsets
41
+ members.map { |m| [ m, self[m].offset ] }
42
+ end
43
+
44
+ # @return [Numeric]
45
+ # Get the offset of a field.
46
+ def offset_of(field_name)
47
+ self[field_name].offset
48
+ end
49
+
50
+ # An enum {Field} in a {StructLayout}.
51
+ class Enum < Field
52
+
53
+ # @param [AbstractMemory] ptr pointer on a {Struct}
54
+ # @return [Object]
55
+ # Get an object of type {#type} from memory pointed by +ptr+.
56
+ def get(ptr)
57
+ type.find(ptr.get_int(offset))
58
+ end
59
+
60
+ # @param [AbstractMemory] ptr pointer on a {Struct}
61
+ # @param value
62
+ # @return [nil]
63
+ # Set +value+ into memory pointed by +ptr+.
64
+ def put(ptr, value)
65
+ ptr.put_int(offset, type.find(value))
66
+ end
67
+
68
+ end
69
+
70
+ class InnerStruct < Field
71
+ def get(ptr)
72
+ type.struct_class.new(ptr.slice(self.offset, self.size))
73
+ end
74
+
75
+ def put(ptr, value)
76
+ raise TypeError, "wrong value type (expected #{type.struct_class})" unless value.is_a?(type.struct_class)
77
+ ptr.slice(self.offset, self.size).__copy_from__(value.pointer, self.size)
78
+ end
79
+ end
80
+
81
+ class Mapped < Field
82
+ def initialize(name, offset, type, orig_field)
83
+ super(name, offset, type)
84
+ @orig_field = orig_field
85
+ end
86
+
87
+ def get(ptr)
88
+ type.from_native(@orig_field.get(ptr), nil)
89
+ end
90
+
91
+ def put(ptr, value)
92
+ @orig_field.put(ptr, type.to_native(value, nil))
93
+ end
94
+ end
95
+ end
96
+ end
@@ -6,6 +6,7 @@ module FFI
6
6
  # ConstGenerator turns C constants into ruby values.
7
7
  #
8
8
  # @example a simple example for stdio
9
+ # require 'ffi/tools/const_generator'
9
10
  # cg = FFI::ConstGenerator.new('stdio') do |gen|
10
11
  # gen.const(:SEEK_SET)
11
12
  # gen.const('SEEK_CUR')
@@ -25,10 +26,10 @@ module FFI
25
26
  #
26
27
  # The only option is +:required+, which if set to +true+ raises an error if a
27
28
  # constant you have requested was not found.
28
- #
29
+ #
29
30
  # @param [#to_s] prefix
30
31
  # @param [Hash] options
31
- # @return
32
+ # @return
32
33
  # @option options [Boolean] :required
33
34
  # @overload initialize(prefix, options)
34
35
  # @overload initialize(prefix, options) { |gen| ... }
@@ -79,7 +80,7 @@ module FFI
79
80
  # @param [#call] converter convert the value from a string to the appropriate
80
81
  # type for {#to_ruby}.
81
82
  # @overload const(name, format=nil, cast='', ruby_name=nil) { |value| ... }
82
- # Use a converter block. This block convert the value from a string to the
83
+ # Use a converter block. This block convert the value from a string to the
83
84
  # appropriate type for {#to_ruby}.
84
85
  # @yieldparam value constant value
85
86
  def const(name, format = nil, cast = '', ruby_name = nil, converter = nil,
@@ -224,6 +225,6 @@ module FFI
224
225
  "#{ruby_name} = #{converted_value}"
225
226
  end
226
227
 
227
- end
228
+ end
228
229
 
229
230
  end
@@ -1,6 +1,51 @@
1
+ require 'ffi/tools/struct_generator'
2
+ require 'ffi/tools/const_generator'
3
+
1
4
  module FFI
2
5
 
3
- # @private
6
+ ##
7
+ # Generate files with C structs for FFI::Struct and C constants.
8
+ #
9
+ # == A simple example
10
+ #
11
+ # In file +zlib.rb.ffi+:
12
+ # module Zlib
13
+ # @@@
14
+ # constants do |c|
15
+ # c.include "zlib.h"
16
+ # c.const :ZLIB_VERNUM
17
+ # end
18
+ # @@@
19
+ #
20
+ # class ZStream < FFI::Struct
21
+ #
22
+ # struct do |s|
23
+ # s.name "struct z_stream_s"
24
+ # s.include "zlib.h"
25
+ #
26
+ # s.field :next_in, :pointer
27
+ # s.field :avail_in, :uint
28
+ # s.field :total_in, :ulong
29
+ # end
30
+ # @@@
31
+ # end
32
+ # end
33
+ #
34
+ # Translate the file:
35
+ # require "ffi/tools/generator"
36
+ # FFI::Generator.new "zlib.rb.ffi", "zlib.rb"
37
+ #
38
+ # Generates the file +zlib.rb+ with constant values and offsets:
39
+ # module Zlib
40
+ # ZLIB_VERNUM = 4784
41
+ #
42
+ # class ZStream < FFI::Struct
43
+ # layout :next_in, :pointer, 0,
44
+ # :avail_in, :uint, 8,
45
+ # :total_in, :ulong, 16
46
+ # end
47
+ #
48
+ # @see FFI::Generator::Task for easy integration in a Rakefile
4
49
  class Generator
5
50
 
6
51
  def initialize(ffi_name, rb_name, options = {})
@@ -34,7 +79,7 @@ module FFI
34
79
  end
35
80
 
36
81
  open @rb_name, 'w' do |f|
37
- f.puts "# This file is generated by rake. Do not edit."
82
+ f.puts "# This file is generated from `#{@ffi_name}'. Do not edit."
38
83
  f.puts
39
84
  f.puts new_file
40
85
  end
@@ -1,25 +1,21 @@
1
- begin
2
- require 'ffi/struct_generator'
3
- require 'ffi/const_generator'
4
- require 'ffi/generator'
5
- rescue LoadError
6
- # from Rakefile
7
- require 'lib/ffi/struct_generator'
8
- require 'lib/ffi/const_generator'
9
- require 'lib/ffi/generator'
10
- end
11
-
1
+ require 'ffi/tools/generator'
12
2
  require 'rake'
13
3
  require 'rake/tasklib'
14
- require 'tempfile'
15
4
 
16
5
  ##
17
- # Rake task that calculates C structs for FFI::Struct.
18
-
19
- # @private
6
+ # Add Rake tasks that generate files with C structs for FFI::Struct and C constants.
7
+ #
8
+ # @example a simple example for your Rakefile
9
+ # require "ffi/tools/generator_task"
10
+ # # Add a task to generate my_object.rb out of my_object.rb.ffi
11
+ # FFI::Generator::Task.new ["my_object.rb"], cflags: "-I/usr/local/mylibrary"
12
+ #
13
+ # The generated files are also added to the 'clear' task.
14
+ #
15
+ # @see FFI::Generator for a description of the file content
20
16
  class FFI::Generator::Task < Rake::TaskLib
21
17
 
22
- def initialize(rb_names)
18
+ def initialize(rb_names, options={})
23
19
  task :clean do rm_f rb_names end
24
20
 
25
21
  rb_names.each do |rb_name|
@@ -28,7 +24,7 @@ class FFI::Generator::Task < Rake::TaskLib
28
24
  file rb_name => ffi_name do |t|
29
25
  puts "Generating #{rb_name}..." if Rake.application.options.trace
30
26
 
31
- FFI::Generator.new ffi_name, rb_name
27
+ FFI::Generator.new ffi_name, rb_name, options
32
28
  end
33
29
  end
34
30
  end
@@ -7,15 +7,15 @@ module FFI
7
7
  #
8
8
  # Given the @@@ portion in:
9
9
  #
10
- # module Zlib::ZStream < FFI::Struct
10
+ # class Zlib::ZStream < FFI::Struct
11
11
  # @@@
12
12
  # name "struct z_stream_s"
13
13
  # include "zlib.h"
14
- #
14
+ #
15
15
  # field :next_in, :pointer
16
16
  # field :avail_in, :uint
17
17
  # field :total_in, :ulong
18
- #
18
+ #
19
19
  # # ...
20
20
  # @@@
21
21
  # end
@@ -90,7 +90,7 @@ module FFI
90
90
  raise "Compilation error generating struct #{@name} (#{@struct_name}):\n#{output}"
91
91
  end
92
92
  end
93
-
93
+
94
94
  output = `#{binary}`.split "\n"
95
95
  File.unlink(binary + (FFI::Platform.windows? ? ".exe" : ""))
96
96
  sizeof = output.shift
@@ -152,7 +152,7 @@ module FFI
152
152
  # also allow to work with the pointer itself. This is useful when you want
153
153
  # a Ruby string already containing a copy of the data, but also the pointer
154
154
  # to the data for you to do something with it, like freeing it, in case the
155
- # library handed the memory to off to the caller (Ruby-FFI).
155
+ # library handed the memory off to the caller (Ruby-FFI).
156
156
  #
157
157
  # It's {typedef}'d as +:strptr+.
158
158
  class StrPtrConverter
@@ -1,3 +1,3 @@
1
1
  module FFI
2
- VERSION = '1.10.0'
2
+ VERSION = '1.11.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.11.0
5
5
  platform: x64-mingw32
6
6
  authors:
7
7
  - Wayne Meissner
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-01-06 00:00:00.000000000 Z
11
+ date: 2019-05-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '10.1'
19
+ version: '12.1'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '10.1'
26
+ version: '12.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake-compiler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -44,14 +44,14 @@ dependencies:
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: 0.6.2
47
+ version: 0.7.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: 0.6.2
54
+ version: 0.7.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
@@ -108,6 +108,7 @@ files:
108
108
  - lib/ffi/autopointer.rb
109
109
  - lib/ffi/buffer.rb
110
110
  - lib/ffi/callback.rb
111
+ - lib/ffi/data_converter.rb
111
112
  - lib/ffi/enum.rb
112
113
  - lib/ffi/errno.rb
113
114
  - lib/ffi/ffi.rb
@@ -162,6 +163,8 @@ files:
162
163
  - lib/ffi/platform/x86_64-windows/types.conf
163
164
  - lib/ffi/pointer.rb
164
165
  - lib/ffi/struct.rb
166
+ - lib/ffi/struct_by_reference.rb
167
+ - lib/ffi/struct_layout.rb
165
168
  - lib/ffi/struct_layout_builder.rb
166
169
  - lib/ffi/tools/const_generator.rb
167
170
  - lib/ffi/tools/generator.rb
@@ -183,7 +186,13 @@ files:
183
186
  homepage: http://wiki.github.com/ffi/ffi
184
187
  licenses:
185
188
  - BSD-3-Clause
186
- metadata: {}
189
+ metadata:
190
+ bug_tracker_uri: https://github.com/ffi/ffi/issues
191
+ changelog_uri: https://github.com/ffi/ffi/blob/master/CHANGELOG.md
192
+ documentation_uri: https://github.com/ffi/ffi/wiki
193
+ wiki_uri: https://github.com/ffi/ffi/wiki
194
+ source_code_uri: https://github.com/ffi/ffi/
195
+ mailing_list_uri: http://groups.google.com/group/ruby-ffi
187
196
  post_install_message:
188
197
  rdoc_options:
189
198
  - "--exclude=ext/ffi_c/.*\\.o$"
@@ -205,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
205
214
  version: '0'
206
215
  requirements: []
207
216
  rubyforge_project:
208
- rubygems_version: 2.7.8
217
+ rubygems_version: 2.7.9
209
218
  signing_key:
210
219
  specification_version: 4
211
220
  summary: Ruby FFI