如何在 C 中返回变量 -> 红宝石界面?
对先前问题的跟进,显示当我尝试从目标库获取错误消息时失败的部分:
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 变量才能返回我的值?
A follow up to an earlier 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. What kind of ruby variable do I need to get my value returned?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
哪一点失败了? 我猜是这样的:
该方法是如何实现的? 该方法的 C 签名是什么? (*字符)?
顺便说一句:冒着听起来像是破纪录的风险,编写 C 扩展比尝试将内容硬塞到 DL 中要容易得多。 AFAIK,除了映射单一功能的一次性黑客之外,没有人使用深度学习。 您提到 FFI 在 Windows 下不起作用,您可能想看看 RubyInline (http ://www.zenspider.com/ZSS/Products/RubyInline/),或者只使用普通的 C 扩展(如果您足够了解 C 来使用 DL,那么您也足够了解 C 来编写扩展)
Which bit fails? I'm guessing it's this:
How is the method implemented? What's the C signature of the method? (*char)?
Btw: at the risk of sounding like broken record, it's MUCH easier to write a C extension than trying to shoehorn things into DL. AFAIK, no one uses DL, apart from maybe one-off hacks to map single functions. You mentioned FFI doesn't work under Windows, you may want to have a look at RubyInline (http://www.zenspider.com/ZSS/Products/RubyInline/), or just use a plain C extension (if you know C well enough to use DL, you know C well enough to write an extension)
FFI
现在可以在 Windows 上运行。以下是在 Ruby 中使用
FFI
的示例,展示了如何将变量从 C 函数返回到 Ruby。FFI
now works on Windows.Here's an example using
FFI
in Ruby that shows how to return a variable from a C function into Ruby.@msg 此时是否已初始化:
如果 @msg 为 nil,DL 可能会将其转换为空指针,当您的 lib 尝试取消引用它时,该指针会崩溃。
Is @msg even initialized at this point:
If @msg is nil, DL will probably cast it to a null pointer which crashes when your lib tries to dereference it.