你如何使用Ruby / DL?这是正确的吗? [英] How do you use Ruby/DL? Is this right?

查看:222
本文介绍了你如何使用Ruby / DL?这是正确的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在RSPEC(ruby flavoured BDD)和Windows应用程序之间编写一个接口。应用程序本身是用一种晦涩的语言编写的,但它有一个C API来提供访问。我已经使用了Ruby / DL,但是即使是最基本的DLL方法调用也很困难。以下是我到目前为止在一个名为gt4r.rb的文件中:

  require'dl / import'

模块Gt4r
扩展DL ::可进入
dlload'c:\\gtdev\\r321 \\\\\gtvapi'

#GTD初始化/终止函数
extern'int GTD_init(char * [],char *,char *)'
extern'int GTD_initialize(char *,char *,char *)'
extern'int GTD_done(void)'
extern'int GTD_get_error_message(int,char **)'
end

到目前为止我的阅读表明这是我需要的所有内容,因此我写了一个RSPEC示例:

  require'gt4r'

@@ test_environment =INCLUDE = C:\\graphtalk \\\\\\\\\\\\\\\\\\\\\\ \ aiadev.ini
@@ normal_user =BMCHARGUE

描述Gt4r do
'初始化'do
rv = Gt4r.gTD_initialize @@ normal_user, @@ normal_u ser,@@ test_environment
rv.should == 0
end
end

运行时......

  C:\ code \GraphTalk> spec -fs -rgt4r gt4r_spec。 rb 

Gt4r
- 初始化(FAILED - 1)

1)
'Gt4r初始化'FAILED
预期:0,
得到:13(使用==)
./gt4r_spec.rb:9:

完成0.031秒

1例子,1次失败

返回值(13)是实际的返回码,意味着错误,但是当我尝试添加gTD_get_error_message时打电话给我的RSPEC,我无法让参数发挥作用。



我是朝着正确的方向前进的,任何人都可以指出下一件我可以尝试的事情吗? / p>

谢谢,
Brett






跟进对于这个问题,显示当我尝试从目标库中获取错误消息时失败的部分:

  require'gt4r' 

@@ t est_environment =INCLUDE = C:\\graphtalk \\env\\aiadev\\config\\aiadev.ini
@@ normal_user =BMCHARGUE

描述Gt4r do
'初始化'do
rv = Gt4r.gTD_initialize @@ normal_user,@@ normal_user,@@ test_environment
Gt4r.gTD_get_error_message rv,@ msg
@ msg.should ==
rv.should == 0
end
end

我希望在@msg中返回错误消息,但是在运行时我得到以下内容:

  Gt4r 
(eval):5:[BUG]分段错误
ruby​​ 1.8.6(2008-08-11)[i386-mswin32]


此应用程序已请求Runtime以不寻常的方式终止它。
请联系应用程序的支持团队以获取更多信息。

如果我使用符号(:msg)代替:

  C:\ code \ GraphTalk \gt4r_dl> spec -fs -rgt4r gt4r_spec.rb 

Gt4r
- 初始化(ERROR - 1)

1)
'Gt4r初始化'中的NoMethodError'
未定义方法`to_ptr':msg:符号
(eval):5:在`call'
(eval):5:in`gTD_get_error_message'
./gt4r_spec.rb:9:

完成0.046秒

1例子,1次失败

显然我遗漏了一些关于在ruby和C之间传递参数的东西,但是什么?

解决方案

普遍的共识是你想尽可能避免使用DL。 (英文)文档很粗略,界面很难用于任何简单的例子。



Ruby本机C接口更容易编程。或者你可以使用FFI,它填充了一个类似于DL的利基,最初来自rubinius项目,最近被移植到普通红宝石。它有一个更好的界面,使用起来痛苦少得多:



http://blog.headius.com/2008/10/ffi-for-ruby-now-available.html


I am trying to write an interface between RSPEC (ruby flavoured BDD) and a Windows application. The application itself is written in an obscure language, but it has a C API to provide access. I've gone with Ruby/DL but am having difficulties getting even the most basic call to a DLL method to work. Here is what I have so far, in a file called gt4r.rb:

require 'dl/import'

module Gt4r
  extend DL::Importable
  dlload 'c:\\gtdev\\r321\\bin\\gtvapi'

  # GTD initialization/termination functions
  extern 'int GTD_init(char *[], char *, char *)'
  extern 'int GTD_initialize(char *, char *, char *)'
  extern 'int GTD_done(void)'
  extern 'int GTD_get_error_message(int, char **)'
end

My reading so far suggests that this is all I need to get going, so I wrote up a RSPEC example:

require 'gt4r'

@@test_environment = "INCLUDE=C:\\graphtalk\\env\\aiadev\\config\\aiadev.ini"
@@normal_user = "BMCHARGUE"

describe Gt4r do
  it 'initializes' do
      rv = Gt4r.gTD_initialize @@normal_user, @@normal_user, @@test_environment
      rv.should == 0
  end
end

And when run...

C:\code\GraphTalk>spec -fs -rgt4r gt4r_spec.rb

Gt4r
- initializes (FAILED - 1)

1)
'Gt4r initializes' FAILED
expected: 0,
     got: 13 (using ==)
./gt4r_spec.rb:9:

Finished in 0.031 seconds

1 example, 1 failure

The return value (13) is an actual return code, meaning an error, but when I try to add the gTD_get_error_message call to my RSPEC, I can't get the parameters to work.

Am I heading in the right direction and can anyone point to the next thing I can try?

Thanks, Brett


A follow up to this question, showing the part that fails when I try to get the error message from my target library:

require 'gt4r'

@@test_environment = "INCLUDE=C:\\graphtalk\\env\\aiadev\\config\\aiadev.ini"
@@normal_user = "BMCHARGUE"

describe Gt4r do
  it 'initializes' do
      rv = Gt4r.gTD_initialize @@normal_user, @@normal_user, @@test_environment
      Gt4r.gTD_get_error_message rv, @msg
      @msg.should == ""
      rv.should == 0
  end
end

I expect the error message to be returned in @msg, but when run I get the following:

Gt4r
(eval):5: [BUG] Segmentation fault
ruby 1.8.6 (2008-08-11) [i386-mswin32]


This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

And this if I use a symbol (:msg) instead:

C:\code\GraphTalk\gt4r_dl>spec -fs -rgt4r gt4r_spec.rb

Gt4r
- initializes (ERROR - 1)

1)
NoMethodError in 'Gt4r initializes'
undefined method `to_ptr' for :msg:Symbol
(eval):5:in `call'
(eval):5:in `gTD_get_error_message'
./gt4r_spec.rb:9:

Finished in 0.046 seconds

1 example, 1 failure

Clearly I am missing something about passing parameters between ruby and C, but what?

解决方案

The general consensus is you want to avoid DL as much as possible. The (english) documentation is quite sketchy and the interface is difficult to use for anything but trivial examples.

Ruby native C interface is MUCH easier to program against. Or you could use FFI, which fills a similiar niche to DL, originally comes from the rubinius project and has recently been ported to "normal" ruby. It has a nicer interface and is much less painful to use:

http://blog.headius.com/2008/10/ffi-for-ruby-now-available.html

这篇关于你如何使用Ruby / DL?这是正确的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆