![](/img/trans.png)
[英]Memory leak in SWIG polymorphism across C++ and Java using directors
[英]Polymorphism across C++ and Ruby using SWIG
我使用SWIG將Ruby腳本包裝在C ++庫中。 在Ruby中,我可以從C ++類繼承,但不能以多態方式將結果指針傳遞給C ++函數。
這是一個具體的例子。 SWIG接口文件使用虛擬函數sound()定義了基類Animal:
[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 Director用於跨語言多態性,但這似乎不起作用。 Ruby腳本如下所示:
[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以某種方式不允許我將Ruby對象視為指向動物的指針。 有任何想法嗎?
我從Tobias Grimm的使用者郵件列表中找到了解決問題的方法。 問題的第一部分是SWIG的誤導性錯誤消息。 該消息似乎表明我將錯誤類型的指針傳遞給了C ++函數,但事實並非如此。 如果在Ruby中檢查異常的類,則為ObjectPreviouslyDeleted,這意味着我的Cat類的基礎C結構指針為NULL。 因此,真正的問題是指針為NULL,而不是指針類型錯誤。
指針為NULL,因為我只是忘記了在Cat的initialize()方法中調用“ super”。 這樣,在創建Cat時,不會分配任何底層C結構,因為從不調用Animal構造函數。 忘記調用“ super”是Ruby初學者經常犯的錯誤,特別是對於像我這樣從C ++來的人來說,他們習慣於自動構造函數鏈接。
因此,我要做的就是添加對“ super”的調用:
class Cat < Animal # Inherit from a C++ class
def initialize
puts "Creating new cat"
super()
end
def sound
puts "Meow"
end
end
現在可以正常工作了。 謝謝托比亞斯。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.