Question

J'essaie d'écrire une interface entre RSPEC (BDD à saveur de rubis) et une application Windows. L'application elle-même est écrite dans un langage obscur, mais elle dispose d'une API C pour fournir un accès. J'ai opté pour Ruby / DL, mais j'ai du mal à faire fonctionner même l'appel le plus élémentaire d'une méthode DLL. Voici ce que j'ai jusqu'à présent, dans un fichier nommé 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

Mes lectures jusqu'à présent suggèrent que c'est tout ce dont j'avais besoin pour commencer, alors j'ai écrit un exemple de 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

Et lorsqu’il est exécuté ...

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

La valeur de retour (13) est un code de retour réel, ce qui signifie une erreur, mais lorsque j'essaie d'ajouter l'appel gTD_get_error_message à mon RSPEC, les paramètres ne fonctionnent pas.

Est-ce que je vais dans la bonne direction et quelqu'un peut-il indiquer la prochaine chose que je peux essayer?

Merci, Brett

Un suivi de cette question, montrant la partie qui échoue lorsque j'essaie d'obtenir le message d'erreur de ma bibliothèque cible:

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

Je m'attends à ce que le message d'erreur soit renvoyé dans @msg, mais lors de l'exécution, le message suivant s'affiche:

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.

Et ceci si j'utilise un symbole (: msg) à la place:

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

Clairement, il me manque quelque chose à propos du passage de paramètres entre ruby ??et C, mais quoi?

Était-ce utile?

La solution

Le consensus général est que vous voulez éviter le plus possible la DL. La documentation (anglaise) est assez sommaire et l'interface est difficile à utiliser, sauf pour des exemples triviaux.

L’interface C native de Ruby est BEAUCOUP plus facile à programmer. Vous pouvez également utiliser FFI, qui remplit un créneau similaire à DL, provient à l'origine du projet rubinius et a récemment été porté à "normal". rubis. Il a une interface plus agréable et est beaucoup moins pénible à utiliser:

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

Autres conseils

  

La valeur de retour (13) est une valeur réelle.   retourne le code, ce qui signifie une erreur, mais   quand j'essaie d'ajouter le   gTD_get_error_message appel à mon   RSPEC, je ne peux pas obtenir les paramètres   travail.

Cela pourrait aider de poster l'erreur au lieu du code qui a fonctionné :)

En gros, une fois que vous commencez à avoir à gérer des pointeurs comme dans (int, char **), les choses deviennent laides.

Vous devez allouer le pointeur de données sur lequel écrire le message, car otherise C n'aura nulle part où écrire les messages d'erreur. Utilisez DL.mallo.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top