你如何在C中返回一个变量 - >红宝石界面?

时间:2008-11-19 10:38:06

标签: c ruby interface ffi rubydl

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

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

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

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.

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

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

显然我遗漏了一些关于在ruby和C之间传递参数的东西。我需要什么样的ruby变量来获取我的值?

3 个答案:

答案 0 :(得分:2)

哪一位失败了?我猜是这样的:

Gt4r.gTD_get_error_message rv, @msg

该方法是如何实施的?这个方法的C签名是什么? (* CHAR)?

顺便说一下:冒着听起来像破纪录的风险,写C扩展比尝试将东西变成DL更容易。 AFAIK,没有人使用DL,除了可能是一次性黑客来映射单个功能。你提到FFI在Windows下不起作用,你可能想看看RubyInline(http://www.zenspider.com/ZSS/Products/RubyInline/),或者只是使用普通的C扩展(如果你知道C足够好使用DL,你知道C足够好写一个扩展名)

答案 1 :(得分:0)

FFI现在适用于Windows。

这是一个在Ruby中使用FFI的示例,它展示了如何将变量从C函数返回到Ruby中。

答案 2 :(得分:-1)

此时@msg是否已初始化:

Gt4r.gTD_get_error_message rv, @msg

如果@msg为nil,DL可能会将它转换为空指针,当你的lib试图取消引用它时崩溃。