![](/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.