2017-10-20 25 views
1

base64でエンコードされたJPEG bytearrayから循環画像を作成するために小さなクラスを作成しましたが、常にsegfaultが発生するようです。これはGJSのカイロ表面を作るのに最も簡単な方法でしたが、私の問題を解決すればクラッタに反対しません。私のGdk/cairoクラスがsegfaultを引き起こすのはなぜですか?

var CircularImage = new Lang.Class({ 
    Name: "CircularImage", 
    Extends: Gtk.DrawingArea, 

    _init: function (bytearray, win, size) { 
     this.parent({ 
      height_request: size, 
      width_request: size 
     }); 

     this.size = size; 

     let image_stream = Gio.MemoryInputStream.new_from_data(
      GLib.base64_decode(bytearray), 
      GLib.free 
     ); 

     let pixbuf = GdkPixbuf.Pixbuf.new_from_stream(
      image_stream, 
      null 
     ) 

     pixbuf.scale_simple(this.size, this.size, GdkPixbuf.InterpType.HYPER); 

     this._surface = Gdk.cairo_surface_create_from_pixbuf(
      pixbuf, 
      0, 
      win.get_window() 
     ); 

     this.connect("draw", (widget, cr) => { 
      this._draw(widget, cr); 
      return false; 
     }); 
    }, 

    _draw: function (widget, cr) { 
     cr.setSourceSurface(this._surface, 0, 0); 
     cr.arc(this.size/2, this.size/2, this.size/2, 0, 2*Math.PI); 
     cr.clip(); 
     cr.paint(); 
    } 
}); 

ありCairoImageSurfaceのための機能や信号を破壊し、私はそれが助けかどうかを確認するためにPIXBUFをunreffingしようとしたように見えるが、これはエラーになりません。

GLib-GObject-WARNING **: g_object_remove_toggle_ref: couldn't find toggle ref 0x7f45456b19e0((nil))

IシンプルなGtkウィンドウでこれを使用していますが、それは動作しますが、セグメンテーションの失敗の原因は半分程度です。私はたいていガベージコレクション言語を使用しているのでメモリ管理についてはほとんど知っていないので、私はこれが解放していないメモリと何らかの関係があると仮定します。

私は間違ったことをしていますか、クラッターでこれを行う簡単な方法か、任意のsegfaultsを追跡できる簡単な方法はありますか?

答えて

2

GJSのメモリ管理は、基本となるライブラリで必要とされている場合でも処理する必要はありません。そうしたら、それはバグです。とにかくそれをやろうとすると、間違いなくクラッシュするでしょう。 (だから、あなたもGJSドキュメントにGLib.free()またはGObject.unref()を呼び出すための任意の手順を参照してください場合 - 。彼らはCのドキュメントから自動生成しているとあってはならない)

残念ながら、メモリ管理を気にする必要は、このようなバグがまだやりますそれらのうちの2つはコードスニペットに関連しています。このような何かを、代わりにhttps://bugzilla.gnome.org/show_bug.cgi?id=747431

あなたが今ヒットしているバグがこれ一つで

let image_stream = Gio.MemoryInputStream.new_from_bytes(
    GLib.base64_decode(bytearray).toGBytes()); 

後に関連するようになるかもしれないもう一つのGJSのバグがあること、あなたはdraw信号あなたに接続するとき現在、カイロのコンテキストでcr.$dispose()を呼び出す必要があります。そうしないと、メモリがリークします。

+0

ありがとう、私は今これを使用することができてうれしいです。 1つの質問ですが、 'cr.paint()'の後にdrawコールバックで 'cr $ dispose()'を呼び出す必要があると思いますか? –

+1

それは正しいです、それは戻る前に最後のものでなければなりません。 – ptomato

+0

これでもう少しテストしましたが、まだメモリリークが発生しているようです。すべてが確実に解放されるように ':: destroy'を行う特別な呼び出しはありますか? –

関連する問題