SWIG를 사용한 C ++ 및 Ruby의 다형성
-
23-08-2019 - |
문제
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과 함께 포인터 만 사용 했으므로 이것이 실제로 작동하는지 또는 다른 것이 있는지 여부는 모르겠습니다. 행운을 빕니다!