Pregunta

Estoy tratando de escribir una interfaz entre RSPEC (BDD con sabor a rubí) y una aplicación de Windows. La aplicación en sí está escrita en un lenguaje oscuro, pero tiene una API C para proporcionar acceso. Fui con Ruby / DL pero tengo dificultades para que funcione incluso la llamada más básica a un método DLL. Esto es lo que tengo hasta ahora, en un archivo llamado 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

Mi lectura hasta ahora sugiere que esto es todo lo que necesito para comenzar, así que escribí un ejemplo 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

Y cuando se ejecuta ...

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

El valor de retorno (13) es un código de retorno real, lo que significa un error, pero cuando intento agregar la llamada gTD_get_error_message a mi RSPEC, no puedo hacer que los parámetros funcionen.

¿Me dirijo en la dirección correcta y alguien puede señalar lo siguiente que puedo intentar?

Gracias Brett


Un seguimiento de esta pregunta, que muestra la parte que falla cuando intento obtener el mensaje de error de mi biblioteca de destino:

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

Espero que el mensaje de error sea devuelto en @msg, pero cuando lo ejecuto obtengo lo siguiente:

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.

Y esto si uso un símbolo (: msg) en su lugar:

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

Claramente me falta algo sobre pasar parámetros entre ruby ??y C, pero ¿qué?

¿Fue útil?

Solución

El consenso general es que desea evitar DL tanto como sea posible. La documentación (en inglés) es bastante incompleta y la interfaz es difícil de usar para cualquier cosa que no sean ejemplos triviales.

La interfaz C nativa de Ruby es MUCHO más fácil de programar. O podría usar FFI, que llena un nicho similar a DL, originalmente proviene del proyecto rubinius y recientemente ha sido portado a "normal". rubí. Tiene una interfaz más agradable y es mucho menos doloroso de usar:

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

Otros consejos

  

El valor de retorno (13) es un valor real   código de retorno, lo que significa un error, pero   cuando trato de agregar el   llamada a gTD_get_error_message a mi   RSPEC, no puedo obtener los parámetros para   trabajo.

Podría ayudar publicar el error en lugar del código que funcionó :)

Básicamente, una vez que comienzas a tener que lidiar con punteros como en (int, char **), las cosas se ponen feas.

Debe asignar el puntero de datos para que se escriba msg, ya que de lo contrario C no tendrá ningún lugar para escribir los mensajes de error. Use DL.mallo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top