【问题标题】:Haskell binding with Ruby through FFI?Haskell 通过 FFI 与 Ruby 绑定?
【发布时间】:2009-03-24 08:10:02
【问题描述】:

由于 ruby​​ 和 Haskell 都支持 FFI,

  • 是否可以通过 FFI 从 ruby​​ 调用 Haskell 代码?
  • Ruby 中有 Haskell 绑定吗?

【问题讨论】:

    标签: ruby haskell ffi libffi


    【解决方案1】:

    我对此讨论有点晚了,但我目前正在编写 Ruby 和 Haskell 之间的桥梁。它位于http://github.com/mwotton/Hubris - 它是在 C 级别工作的绑定。不过,仍处于非常早期的开发阶段。

    【讨论】:

      【解决方案2】:

      GHC 6.12.1 支持在 Linux 上构建动态库。尝试类似:

      Example.hs

      {-# LANGUAGE ForeignFunctionInterface #-}
      
      module Example where
      
      import Foreign.C.Types
      
      fibonacci :: Int -> Int
      fibonacci n = fibs !! n
          where fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
      
      fibonacci_hs :: CInt -> CInt
      fibonacci_hs = fromIntegral . fibonacci . fromIntegral
      
      foreign export ccall fibonacci_hs :: CInt -> CInt
      

      包装器.c

      #include <stdlib.h>
      
      #include "HsFFI.h"
      
      void
      example_init (void)
      {
        hs_init (NULL, NULL);
      }
      
      void
      example_exit (void)
      {
        hs_exit ();
      }
      

      script.rb

      require 'dl'
      require 'dl/import'
      
      module Example
          extend DL::Importable
          dlload "./libffi-example.so"
          extern "void example_init()"
          extern "void example_exit()"
          extern "int fibonacci_hs(int)"
      end
      
      Example.example_init
      
      1.upto( 40 ) do | x |
          puts "#{ x } -> #{ Example.fibonacci_hs x }\n"
      end
      
      Example.example_exit
      

      生成文件

      GHC=ghc-6.12.1
      
      libffi-example.so: Example.o wrapper.o Example_stub.o
          $(GHC) -o $@ -shared -dynamic -fPIC $^ -lHSrts-ghc6.12.1
      
      Example_stub.c Example_stub.h Example.o: Example.hs
          $(GHC) -c -dynamic -fPIC Example.hs
      
      Example_stub.o: Example_stub.c
          $(GHC) -c -dynamic -fPIC Example_stub.c
      
      wrapper.o: wrapper.c Example_stub.h
          $(GHC) -c -dynamic -fPIC wrapper.c
      
      clean:
          rm -f *.hi *.o *_stub.[ch] *.so
      

      要运行的命令

      make
      ruby script.rb
      

      【讨论】:

        【解决方案3】:

        我以前没见过,但这是可能的。

        • 使用 Haskell 的 FFI 包装 libruby。您的主要可执行文件将用 Haskell 编写,它将调用 ruby_init() 和相关函数,以便在进程中运行 Ruby 解释器。不过,这确实允许您运行任意 Ruby 代码。
        • 使用 Ruby 的 FFI 包装 GHC 模块 as a library。您的 Ruby 脚本必须调用 hs_init(),并且只能访问 foreign exported 函数。

        您需要使用 C 语言编写胶水代码,以使这两个选项中的任何一个都能正常工作。

        • 在不同的进程中运行 Ruby 和 Haskell,使用一些 IPC 在它们之间进行通信。也许 XML-RPC (Haskell/Ruby) 或 JSON (Haskell/Ruby) 通过套接字,或者甚至只是使用您自己的自定义协议的管道。

        我不知道你的要求是什么,但这是我想要的——它更容易。

        【讨论】:

          【解决方案4】:

          我不确定 Haskell 方面,但这里有一段来自 Mountain West Ruby Conf 09 的精彩视频,内容是关于使用 Ruby 的 FFI。它看起来像一个非常漂亮的界面。

          http://mwrc2009.confreaks.com/13-mar-2009-16-10-ffi-jeremy-hinegardner.html

          【讨论】:

            【解决方案5】:

            @ephemient,我实际上正在寻找使用 Ruby(高级 + 动态)作为主要控制器逻辑并调用 haskell 进行大量数据处理(功能 + 速度)的方法

            我认为原生绑定几乎不存在,除了这条推文http://twitter.com/BlurredWeasel/status/1321484127

            使用 JSON RPC 可能是最简单的实现方法,其中 ruby​​ 中有一个瘦包装器 (method_missing) 以通过 JSON/Socket 调用 haskell。

            JSON 的优点是能够轻松地将原语映射到各种语言之间的原生类型。

            class SciHs
              def method_missing(method, *args) 
                 // json encode
                 // request Haskell over tcp socket or unix pipes
                 // json decode
              end
            end 
            

            ruby 中快速数字运算的其他替代方法(+ 函数式)

            • Ruby 中的 NArray 或其他科学库
            • GNU 科学库的 Ruby 绑定
            • 或转到 ruby​​ 1.9 并使用 YARV2LLVM 将计算逻辑 JIT 到 LLVM 中以加快执行速度。

            有人想吗?

            【讨论】:

            【解决方案6】:

            我确实尝试过这个(我是提到的推文中的那个)。

            我没有想到 libruby 方法,但我花了相当多的钱尝试使用 ruby​​ 的 FFI 来包装从 haskell 导出的函数,但始终无法将其全部链接并运行。

            如果您查看 haskell 的 FFI 示例,您会发现它们都包含 C main() 函数。由于 ruby​​ 的 FFI 没有(也不能有)main(),所以这行不通。如果你不这样做,你最终会出现奇怪的链接错误。

            我可以与你分享我拥有的东西,在 freenode (cschneid) 或 twitter (BlurredWeasel) 上 ping 我。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-07-28
              相关资源
              最近更新 更多