【发布时间】:2009-06-22 00:04:05
【问题描述】:
我想使用 Ruby 访问 DLL 中的函数。我想使用 C 的低级访问,同时仍然保持编写 Ruby 代码的简单性。我该如何做到这一点?
【问题讨论】:
我想使用 Ruby 访问 DLL 中的函数。我想使用 C 的低级访问,同时仍然保持编写 Ruby 代码的简单性。我该如何做到这一点?
【问题讨论】:
看看Win32APIstdlib。它是 Windows 32 API 或 DLL 的一个相当简单(但晦涩)的接口。
Documentation is here,一些examples here。让你尝尝:
require "Win32API"
def get_computer_name
name = " " * 128
size = "128"
Win32API.new('kernel32', 'GetComputerName', ['P', 'P'], 'I').call(name, size)
name.unpack("A*")
end
【讨论】:
您可以使用 Fiddle:http://ruby-doc.org/stdlib-2.0.0/libdoc/fiddle/rdoc/Fiddle.html
Fiddle 是一个鲜为人知的模块,在 1.9.x 中被添加到 Ruby 的标准库中。它允许您直接与来自 Ruby 的 C 库进行交互。
它通过包装 libffi 来工作,这是一个流行的 C 库,它允许用一种语言编写的代码调用用另一种语言编写的方法。如果你没听说过,“ffi”代表“外来函数接口”。而且您不仅限于 C。一旦您学习了 Fiddle,您就可以使用用 Rust 和其他支持它的语言编写的库。
require 'fiddle'
libm = Fiddle.dlopen('/lib/libm.so.6')
floor = Fiddle::Function.new(
libm['floor'],
[Fiddle::TYPE_DOUBLE],
Fiddle::TYPE_DOUBLE
)
puts floor.call(3.14159) #=> 3.0
或
require 'fiddle'
require 'fiddle/import'
module Logs
extend Fiddle::Importer
dlload '/usr/lib/libSystem.dylib'
extern 'double log(double)'
extern 'double log10(double)'
extern 'double log2(double)'
end
# We can call the external functions as if they were ruby methods!
puts Logs.log(10) # 2.302585092994046
puts Logs.log10(10) # 1.0
puts Logs.log2(10) # 3.321928094887362
【讨论】:
我认为你也可以使用 ruby/dl http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/95a483230caf3d39
或 ffi 使其更容易和跨 VM 更友好:
【讨论】:
Hiroshi Hatake 和 Daniel Berger 有开源 win32-api“Win32API 的替代品”。它适用于 Ruby 1.8、1.9 和 2.X。
【讨论】: