【问题标题】:How to manage the Ruby Garbage collector with swig如何使用 swig 管理 Ruby 垃圾收集器
【发布时间】:2015-02-05 11:41:18
【问题描述】:

我有一个 C++ 接口,我用 swig 为它创建了 ruby​​ 绑定。我能够构建这些绑定,但垃圾收集器有问题。我的 ruby​​ 代码如下所示:

parser = HeaderParser.new(source_file, ['/usr/lib'])
parser.parse
functions = parser.getFunctions //Array of Ruby wrapped class named  Function

functions.each do |f|
  puts f.getName
end

问题在于,如果垃圾收集器删除解析器对象,所有对 Function 对象方法的调用都会导致 Segfault。那是因为我的 C++ Function 对象只使用指向 Parser 对象分配的内存的指针。

我想找到一种方法告诉 GC 在使用 Function 对象时不要释放 HeaderParser 对象

我尝试过使用像

这样的指令
%trackbobjects 

并像文档中那样为垃圾收集器编写一个 ruby​​ 标记函数,但没有成功

%header %{
  static void mark_HeaderParser(void* ptr) {
  TruckBoris::HeaderParser* hp = (TruckBoris::HeaderParser*) ptr;

  /* Loop over each object and tell the garbage collector
  that we are holding a reference to them. */
  std::vector<TruckBoris::Function> fns;
  fns = hp->getFunctions();
  int count = fns.size();

  for(int i = 0; i < count; ++i) {
    TruckBoris::Function fn = fns[i];
    VALUE object = SWIG_RubyInstanceFor(&fn);

    if (object != Qnil) {
      rb_gc_mark(object);
    }
  }
  }
%}

有关 C++ 接口的信息 我有一个初始化 Clang CompilerInstance 和 ASTConsumer 的主类:

class HeaderParser
{
  public:
    HeaderParser();
    HeaderParser( std::string sourceFile, std::vector<std::string> headersPaths);
    ~HeaderParser();
    ...
    bool parse(bool mainFile = false);
    ...
    std::vector<Function> getFunctions() const;
    ...
private:
    ...
    clang::CompilerInstance m_ci;
    HeaderElements *m_headerElements; // an ASTConsumer
};

当调用 HeaderParser::parse 方法时,它会解析一个源文件并填充一个 Function 对象的向量。

那些对象只是使用 FunctionDecl 指针指向由 HeaderParser 中的 compilerInstance 分配的内存。

class Function 
{
 public:
   Function();
   Function(clang::FunctionDecl * fn);
   ~Function() {}
   std::string getName() const; 
 private:
   clang::FunctionDecl * m_function;
};

所以 Function 类的方法是这样构造的:

std::string Function::getName() const
{
  if(m_function)
    return m_function->getNameInfo().getAsString();
  else
    return std::string();
}

【问题讨论】:

    标签: c++ ruby swig


    【解决方案1】:

    我只需要简化所有操作即可。

    在 HeaderParser 类中,而不是直接返回 std::vector&lt;Function&gt;

    std::vector<Function> getFunctions() const;
    

    我用过:

    int nbFunctions() const;
    Function getFunction(int) const;
    

    并且,删除标记指令,让 swig 发挥作用。之后我只需要添加我的 ruby​​ lib 文件:

    class Rtruckboris::HeaderParser
      def functions
        fns=[]
        (0..(functions_num() -1)).each do |i|
          fns<<get_nth_function(i)
        end
        fns
      end 
    ...
    

    【讨论】:

      猜你喜欢
      • 2016-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多