문제

SWIG를 사용하여 C ++ 라이브러리 주위에 Ruby 스크립트를 포장합니다. 루비에서는 C ++ 클래스에서 상속 될 수 있지만 그 결과 포인터를 다형성 방식으로 C ++ 함수로 전달할 수는 없습니다.

구체적인 예가 있습니다. SWIG 인터페이스 파일은 가상 함수 sound ()로 기본 클래스 동물을 정의합니다.

[animals.i]
%module(directors="1") animals
%{
#include "animals.h"
%}

// Apply the 'director' feature to a virtual function,
// so that we can override it in Ruby.
%feature("director") Animal::sound;
class Animal {
public:
    Animal();
    virtual ~Animal();
    virtual void sound();
};

class Dog : public Animal {
public:
    Dog();
    virtual ~Dog();
    virtual void sound();
};

// This function takes an Animal* and calls its virtual function sound().
void kick(Animal*, int);   

나는 언어 간 다형성을 위해 SWIG 감독을 사용하지만 이것은 효과가없는 것 같습니다. 루비 스크립트는 다음과 같습니다.

[tst.rb]
require 'animals'
include Animals

dog= Dog.new   # Instantiate C++ class
kick(dog, 3)   # Kick the dog 3 times => It barks 3 times.
               # So far so good.

class Cat < Animal   # Inherit from a C++ class
   def initialize
      puts "Creating new cat"
   end

   def sound
      puts "Meow"
   end
end

cat= Cat.new   # Instantiate Ruby class

kick(cat, 9)   # This does not fly.

스크립트의 마지막 줄은 다음 오류를 일으 킵니다.

Expected argument 0 of type Animal *, but got Cat #<Cat:0xb7d621c8>

그래서 어떻게 든 SWIG는 루비 물체를 포인터 간 동물로 취급 할 수 없습니다. 어떤 아이디어?

도움이 되었습니까?

해결책

SWIG 사용자 메일 링리스트의 Tobias Grimm의 문제에 대한 해결책을 얻었습니다. 문제의 첫 번째 부분은 SWIG의 오도 오류 메시지입니다. 메시지는 C ++ 기능에 잘못된 유형의 포인터를 전달한다고 제안하는 것 같습니다. 그러나 이것은 그렇지 않습니다. Ruby에서 예외의 클래스를 확인하면 대상이되며, 이는 Cat 클래스의 기본 C 구조 포인터가 NULL임을 의미합니다. 따라서 실제 문제는 포인터가 무효이며 잘못된 유형이 아니라는 것입니다.

Cat 's Initialize () 메소드에서 "Super"를 호출하는 것을 잊었 기 때문에 포인터는 NULL입니다. 이런 식으로, 고양이가 생성되면 동물 생성자가 결코 호출되지 않기 때문에 기본 C 구조물이 할당되지 않습니다. 'Super'라고 부르는 것을 잊어 버리는 것은 매우 일반적인 루비 -Beginner의 실수입니다. 특히 자동 생성자 체인에 익숙한 C ++ 출신의 나와 같은 사람들에게는 매우 일반적인 실수입니다.

그래서 내가해야 할 일은 'Super'에 전화를 추가 한 것입니다.

class Cat < Animal   # Inherit from a C++ class
   def initialize
      puts "Creating new cat"
      super()
   end
   def sound
      puts "Meow"
   end
end

이것은 이제 잘 작동합니다. 고마워요, 토비아스.

다른 팁

나는 당신이 a를 정의해야한다고 생각합니다 도우미 기능 그것은 당신의 인스턴스에 대한 포인터를 반환합니다. 나는 Fopen과 함께 포인터 만 사용 했으므로 이것이 실제로 작동하는지 또는 다른 것이 있는지 여부는 모르겠습니다. 행운을 빕니다!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top