Reputation: 440
I'm writting a little http client to test api calls. This is the occasion for learning vala and using gtk3.
I made a class to deal with gtk interface and http request.
using GLib;
using Gtk;
public class RequestHandler : Object
{
public string uri { get; private set; default = ""; }
// Constructor
public RequestHandler ()
{
}
[CCode (instance_pos = -1)]
public void on_url_changed (Entry entry, Button button)
{
stderr.printf ("this#%p\n", this);
if (entry.get_text_length () == 0)
{
button.set_sensitive (false);
this.uri = "";
}
else
{
button.set_sensitive (true);
this.uri = entry.get_text();
}
}
[CCode (instance_pos = -1)]
public void on_send_clicked (Button button)
{
assert (this.uri != null );
stderr.printf ("Send request to : %s\n", this.uri);
}
}
The line
stderr.printf ("this#%p\n", this);
// => fprintf (_tmp0_, "this#%p\n", self); in the C file
display every time "this#0x1" and the program failed with segmentation fault at the line
this.uri = entry.get_text();
// _g_free0 (self->priv->_uri); in the C file
The UI is build with
var builder = new Builder ();
builder.add_from_file (UI_FILE);
var signals_handler = new RequestHandler ();
builder.connect_signals (signals_handler);
I'm really a newbie in vala and I don't see my mistake.
[edit]
...
<object class="GtkEntry" id="entry2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
<property name="input_purpose">url</property>
<signal name="changed" handler="request_handler_on_url_changed" object="button1" swapped="no"/>
</object>
...
The ui is fully generated with glade.
Upvotes: 0
Views: 420
Reputation: 17522
You have an extra argument on the on_url_changed method. The Gtk.Editable.changed signal should have a single argument: the Gtk.Editable which changed. Since there is no type safety with autoconnected signals, public void on_changed (Gtk.Entry entry);
should work.
What is happening with the code you posted above is that something like this is being generated:
void request_handler_on_changed (GtkEntry* entry, GtkButton* button, RequestHandler* self) {
fprintf (stderr, "this#%p\n", self);
}
And gtk+ is calling it like
request_handler_on_changed (editable, request_handler);
So, when your Vala code gets the information, it has the RequestHandler in the button argument, and self (which is how the "this" variable is generated) is garbage.
You have to be very careful when autoconnecting signals because you're basically circumventing Vala and hooking directly in to the generated C. Vala has no way to provide type safety.
Upvotes: 1