【问题标题】:How can I load Windows DLL files with Ruby fiddle?如何使用 Ruby fiddle 加载 Windows DLL 文件?
【发布时间】:2019-11-23 09:50:39
【问题描述】:

我正在尝试为 ruby​​ 创建一个 GR framework 绑定。 我用小提琴。 Fiddle 是使用 ruby​​ 翻译外部函数接口 (FFI) 的默认扩展。它在 Linux 和 Mac 上运行良好。但在 Windows 上,我收到以下错误。

代码 hoge.rb

require 'fiddle/import'

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

错误

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 效果很好。

require 'ffi'

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

但这次我想使用 fiddle 而不是 ruby​​-ffi。 接下来我该怎么做?

【问题讨论】:

  • DLL 可能依赖于 Fiddle 找不到的其他 DLL。再试一次,但在加载 DLL 之前调用SetDllDirectory()gr/bin 文件夹添加到搜索路径。
  • 谢谢你。你是对的!现在可以了。
  • 也许发布一个实际可行的解决方案示例,以便其他人可能会发现这更有帮助?

标签: ruby windows dll fiddle ruby-ffi


【解决方案1】:

我自己回答问题。

1.使用RubyInstaller::Runtime.add_dll_directory

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

  • 对于所有 DLL 搜索,都会忽略 PATH 环境变量。
  • 环境变量RUBY_DLL_PATH 在 ruby​​ 启动时被解释 - 以后的更改不会影响正在运行的进程。
  • 使用 Ruby 函数 add_dll_directory 对 DLL 搜索路径进行运行时更改。

2。使用SetDllDirectory()

或者,您可以运行 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))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-21
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多