5

I am trying to create a GR framework binding for ruby. I use Fiddle. Fiddle is a default extension to translate a foreign function interface (FFI) with ruby. It Works well on Linux and Mac. But on Windows, I got following error.

code hoge.rb

require 'fiddle/import'

module M
   extend extend Fiddle::Importer
   dlload File.expand_path('gr/bin/libGR.dll').gsub("/", "\\")
end

error

Traceback (most recent call last):
        7: from hoge.rb:3:in `<main>'
        6: from hoge.rb:5:in `<module:M>'
        5: from C:/Ruby26-x64/lib/ruby/2.6.0/fiddle/import.rb:77:in `dlload'
        4: from C:/Ruby26-x64/lib/ruby/2.6.0/fiddle/import.rb:77:in `collect'
        3: from C:/Ruby26-x64/lib/ruby/2.6.0/fiddle/import.rb:87:in `block in dlload'
        2: from C:/Ruby26-x64/lib/ruby/2.6.0/fiddle.rb:47:in `dlopen'
        1: from C:/Ruby26-x64/lib/ruby/2.6.0/fiddle.rb:47:in `new'
C:/Ruby26-x64/lib/ruby/2.6.0/fiddle.rb:47:in `initialize': No such file or directory (Fiddle::DLError)
        5: from hoge.rb:3:in `<main>'
        4: from hoge.rb:5:in `<module:M>'
        3: from C:/Ruby26-x64/lib/ruby/2.6.0/fiddle/import.rb:77:in `dlload'
        2: from C:/Ruby26-x64/lib/ruby/2.6.0/fiddle/import.rb:77:in `collect'
        1: from C:/Ruby26-x64/lib/ruby/2.6.0/fiddle/import.rb:86:in `block in dlload'
C:/Ruby26-x64/lib/ruby/2.6.0/fiddle/import.rb:89:in `rescue in block in dlload': can't load C:\Users\kojix2\gr\bin\libgr.dll (Fiddle::DLError)
  • Windows 10
  • Ruby 2.6.5 + DevKit

ruby-ffi works well.

require 'ffi'

module M
   extend FFI::Library
   ffi_lib File.expand_path('gr/bin/libGR.dll').gsub("/", "\\")
end

But I want to use fiddle instead of ruby-ffi in this time. What should I do next?

kojix2
  • 806
  • 7
  • 18
  • 1
    The DLL likely depends on other DLLs which Fiddle can't find. Try it again but call `SetDllDirectory()` to add the `gr/bin` folder to the search path before loading the DLL. – cremno Nov 23 '19 at 10:31
  • Thank you cremno. you're right! Now It works. – kojix2 Nov 23 '19 at 12:23
  • 1
    perhaps post an actual example of working solution so that others may find this more helpful? – lacostenycoder Nov 23 '19 at 17:25

1 Answers1

3

I answer my own questions.

1. Use RubyInstaller::Runtime.add_dll_directory

DLL loading https://github.com/oneclick/rubyinstaller2/wiki/For-gem-developers#-dll-loading

  • The PATH environment variable is ignored for all DLL searches.
  • Environment variable RUBY_DLL_PATH is interpreted at the ruby startup - later changes doesn't affect the running process.
  • Use the Ruby function add_dll_directory to do runtime changes to DLL search paths.

2. Use SetDllDirectory()

Alternatively, you can run SetDllDirectory.

require 'fiddle/import'
require 'fiddle/types'
module WinAPI
  extend Fiddle::Importer
  dlload 'kernel32.dll'
  include Fiddle::Win32Types
  extern 'int SetDllDirectory(LPCSTR)'
end
WinAPI.SetDllDirectory(File.expand_path(path))
kojix2
  • 806
  • 7
  • 18