Как вы возвращаете переменную в интерфейсе C -> ruby? - PullRequest
0 голосов
/ 19 ноября 2008

Продолжение предыдущего вопроса, показывающее, что происходит сбой при попытке получить сообщение об ошибке из целевой библиотеки:

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 ​​мне нужен, чтобы получить возвращенное значение?

Ответы [ 3 ]

2 голосов
/ 19 ноября 2008

Какой бит не работает? Я предполагаю, что это так:

Gt4r.gTD_get_error_message rv, @msg

Как реализован метод? Что такое сигнатура C метода? (* Символы)

Кстати: рискуя звучать как неработающая запись, НАМНОГО проще написать расширение C, чем пытаться вставить вещи в DL. AFAIK, никто не использует DL, кроме, возможно, одноразовых взломов для отображения отдельных функций. Вы упомянули, что FFI не работает под Windows, возможно, вы захотите взглянуть на RubyInline (http://www.zenspider.com/ZSS/Products/RubyInline/), или просто использовать простое расширение C (если вы знаете C достаточно хорошо, чтобы использовать DL, вы знаете C достаточно хорошо, чтобы написать расширение)

0 голосов
/ 06 января 2013

FFI теперь работает в Windows.

Вот пример использования FFI в Ruby, который показывает, как вернуть переменную из функции C в Ruby.

0 голосов
/ 19 ноября 2008

Является ли @msg даже инициализированным в этой точке:

Gt4r.gTD_get_error_message rv, @msg

Если @msg равен nil, DL, вероятно, преобразует его в нулевой указатель, который вылетает, когда ваша библиотека пытается его разыменовать.

...