我正在尝试编写 RSPEC(ruby 风格的 BDD)和 Windows 应用程序之间的接口。应用程序本身是用一种晦涩难懂的语言编写的,但它有一个 C API 来提供访问权限。我已经使用 Ruby/DL,但即使是最基本的 DLL 方法调用也很难工作。这是我目前在一个名为 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
到目前为止,我的阅读表明这就是我所需要的,所以我写了一个 RSPEC 示例:
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
而运行时...
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
返回值 (13) 是一个实际的返回代码,表示错误,但是当我尝试将 gTD_get_error_message 调用添加到我的 RSPEC 时,我无法让参数正常工作。
我是否朝着正确的方向前进,任何人都可以指出我可以尝试的下一件事吗?
谢谢,布雷特
对此问题的跟进,显示了当我尝试从目标库中获取错误消息时失败的部分:
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 之间传递参数的东西,但是什么?