c - 呼び出し - ruby youtube api




あなたはどのようにRuby/DLを使いますか? これは正しいですか? (2)

私は、RSPEC(ルビー風味の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)はエラーを意味する実際の戻りコードですが、RSPECにgTD_get_error_message呼び出しを追加しようとすると、パラメータを取得できません。

私は正しい方向に向かい、次のことを誰かが指摘できますか?

ありがとう、ブレット

私のターゲットライブラリからエラーメッセージを取得しようとすると失敗する部分を示す、この質問へのフォローアップ:

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

明らかに、私はルビーとCの間でパラメータを渡すことについて何か不足していますが、何ですか?


戻り値(13)はエラーを意味する実際の戻りコードですが、RSPECにgTD_get_error_message呼び出しを追加しようとすると、パラメータを取得できません。

それは働いたコードの代わりにエラーを投稿するのに役立つかもしれません:)

基本的には、(int、char **)のようにポインタを処理しなければならないと、状況が悪くなります。


一般的な合意は、可能な限りDLを避けたいということです。 (英語の)ドキュメンテーションは非常にスケッチであり、インターフェイスは簡単な例以外には使用するのが難しいです。

RubyネイティブCインターフェイスは、プログラミングが簡単です。 または、DLに類似したニッチを埋めるFFIを使用することもできます。これはもともとrubiniusプロジェクトから来ており、最近「通常の」ルビに移植されました。 それはより良いインターフェースを持ち、使用するのがずっと苦痛です。

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







rubydl