2008-11-06 2 views
3

RSPEC (루비 맛 BDD)과 Windows 응용 프로그램간에 인터페이스를 작성하려고합니다. 응용 프로그램 자체는 모호한 언어로 작성되었지만 액세스를 제공하는 C API가 있습니다. 나는 Ruby/DL을 사용했지만, DLL 메소드에 대한 가장 기본적인 호출조차도 어려움을 겪고있다. 여기에 내가 지금까지 무엇을 가지고라는 파일 gt4r.rb의 :Ruby/DL은 어떻게 사용합니까? 이게 옳은 거니?

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 호출을 추가하려고 할 때, 내가 얻을 수 없다 작동하는 매개 변수

나는 올바른 방향으로 나아가고 있으며 누구나 다음에 시도 할 수있는 점을 지적 할 수 있습니까?

감사합니다, 브렛


A I 내 목표 라이브러리에서 오류 메시지가하려고 할 때 실패 부분을 보여,이 질문에 대한 후속 : 나는 기대

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,하지만 사이에 매개 변수를 전달 대해 뭔가를 놓친 거지
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 

?

답변

7

일반적으로 가능한 한 DL을 피하기를 원합니다. (영어) 문서는 매우 개략적이며 인터페이스는 사소한 예문 이외에는 사용하기가 어렵습니다.

루비 네이티브 C 인터페이스는 프로그램하기가 훨씬 쉽습니다. 또는 DL에 유사한 틈새 시장을 채우는 FFI를 사용할 수 있는데, 원래는 rubinius 프로젝트에서 왔으며 최근에 "정상적인"루비로 이식되었습니다. 그것은 더 좋은 인터페이스를 가지고 있으며 훨씬 덜 고통스러운 사용하는 것입니다

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

+0

FFI에서 지금까지 읽은 내용은 흥미로운 것 같습니다. 내가 시도해 볼게. – Brett

+0

hmmm ... 창문에서 작동하지 않는다 – Brett

+0

ffi gem이 창문에서 작동 함 [적어도 devkit을 사용하여 mingw] – rogerdpack

1

반환 값은 (13) 에러를 의미, 실제 리턴 코드이지만, 내가 를 추가 할 때 내 RSPEC에 대한 gTD_get_error_message 호출, 매개 변수를 으로 가져올 수 없습니다. 그것은 일 :

기본적으로, 당신은 (INT, 문자 **)처럼 포인터를 처리하는 것을 시작하면 대신 코드의 오류를 게시 도움이 될

는 상황이 추한.

+0

너무 사실 - 나는 추한 부분을 피하려고했습니다. :) 나는 작동하지 않는 매개 변수를 다루는 후속 질문을 할 것입니다. 건배, 브렛 – Brett

0

당신은 MSG가 기록 될 수 있도록 otherise C는 오류 메시지를 작성하는 곳이 없습니다 때문에, 데이터 포인터를 할당해야합니다. DL.mallo를 사용하십시오.