⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.10
Server IP:
157.245.101.34
Server:
Linux skvinfotech-website 5.4.0-131-generic #147-Ubuntu SMP Fri Oct 14 17:07:22 UTC 2022 x86_64
Server Software:
Apache/2.4.41 (Ubuntu)
PHP Version:
7.4.33
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
doc
/
libglib2.0-doc
/
gobject
/
View File Name :
chapter-signal.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>The GObject messaging system: GObject Reference Manual</title> <meta name="generator" content="DocBook XSL Stylesheets V1.79.1"> <link rel="home" href="index.html" title="GObject Reference Manual"> <link rel="up" href="pt01.html" title="Part I. Concepts"> <link rel="prev" href="gobject-properties.html" title="Object properties"> <link rel="next" href="signal.html" title="Signals"> <meta name="generator" content="GTK-Doc V1.32 (XML mode)"> <link rel="stylesheet" href="style.css" type="text/css"> </head> <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"> <table class="navigation" id="top" width="100%" summary="Navigation header" cellpadding="2" cellspacing="5"><tr valign="middle"> <td width="100%" align="left" class="shortcuts"></td> <td><a accesskey="h" href="index.html"><img src="home.png" width="16" height="16" border="0" alt="Home"></a></td> <td><a accesskey="u" href="pt01.html"><img src="up.png" width="16" height="16" border="0" alt="Up"></a></td> <td><a accesskey="p" href="gobject-properties.html"><img src="left.png" width="16" height="16" border="0" alt="Prev"></a></td> <td><a accesskey="n" href="signal.html"><img src="right.png" width="16" height="16" border="0" alt="Next"></a></td> </tr></table> <div class="chapter"> <div class="titlepage"><div><div><h2 class="title"> <a name="chapter-signal"></a>The GObject messaging system</h2></div></div></div> <div class="toc"><dl class="toc"> <dt><span class="sect1"><a href="chapter-signal.html#closure">Closures</a></span></dt> <dd><dl> <dt><span class="sect2"><a href="chapter-signal.html#id-1.3.5.2.5">C Closures</a></span></dt> <dt><span class="sect2"><a href="chapter-signal.html#id-1.3.5.2.6">Non-C closures (for the fearless)</a></span></dt> </dl></dd> <dt><span class="sect1"><a href="signal.html">Signals</a></span></dt> <dd><dl> <dt><span class="sect2"><a href="signal.html#signal-registration">Signal registration</a></span></dt> <dt><span class="sect2"><a href="signal.html#signal-connection">Signal connection</a></span></dt> <dt><span class="sect2"><a href="signal.html#signal-emission">Signal emission</a></span></dt> <dt><span class="sect2"><a href="signal.html#signal-detail">The <span class="emphasis"><em>detail</em></span> argument</a></span></dt> </dl></dd> </dl></div> <div class="sect1"> <div class="titlepage"><div><div><h2 class="title" style="clear: both"> <a name="closure"></a>Closures</h2></div></div></div> <p> Closures are central to the concept of asynchronous signal delivery which is widely used throughout GTK+ and GNOME applications. A closure is an abstraction, a generic representation of a callback. It is a small structure which contains three objects: </p> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <li class="listitem"> <p>a function pointer (the callback itself) whose prototype looks like: </p> <div class="informalexample"> <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td class="listing_lines" align="right"><pre>1</pre></td> <td class="listing_code"><pre class="programlisting"><span class="n">return_type</span> <span class="nf">function_callback</span> <span class="p">(</span><span class="err">…</span> <span class="p">,</span> <span class="n">gpointer</span> <span class="n">user_data</span><span class="p">);</span></pre></td> </tr> </tbody> </table> </div> <p> </p> </li> <li class="listitem"><p> the <em class="parameter"><code>user_data</code></em> pointer which is passed to the callback upon invocation of the closure </p></li> <li class="listitem"><p> a function pointer which represents the destructor of the closure: whenever the closure's refcount reaches zero, this function will be called before the closure structure is freed. </p></li> </ul></div> <p> </p> <p> The <a class="link" href="gobject-Closures.html#GClosure"><span class="type">GClosure</span></a> structure represents the common functionality of all closure implementations: there exists a different closure implementation for each separate runtime which wants to use the GObject type system. <a href="#ftn.id-1.3.5.2.3.2" class="footnote" name="id-1.3.5.2.3.2"><sup class="footnote">[4]</sup></a> The GObject library provides a simple <a class="link" href="gobject-Closures.html#GCClosure" title="struct GCClosure"><span class="type">GCClosure</span></a> type which is a specific implementation of closures to be used with C/C++ callbacks. </p> <p> A <a class="link" href="gobject-Closures.html#GClosure"><span class="type">GClosure</span></a> provides simple services: </p> <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "> <li class="listitem"><p> Invocation (<code class="function"><a class="link" href="gobject-Closures.html#g-closure-invoke" title="g_closure_invoke ()">g_closure_invoke</a></code>): this is what closures were created for: they hide the details of callback invocation from the callback invoker.</p></li> <li class="listitem"><p> Notification: the closure notifies listeners of certain events such as closure invocation, closure invalidation and closure finalization. Listeners can be registered with <code class="function"><a class="link" href="gobject-Closures.html#g-closure-add-finalize-notifier" title="g_closure_add_finalize_notifier ()">g_closure_add_finalize_notifier</a></code> (finalization notification), <code class="function"><a class="link" href="gobject-Closures.html#g-closure-add-invalidate-notifier" title="g_closure_add_invalidate_notifier ()">g_closure_add_invalidate_notifier</a></code> (invalidation notification) and <code class="function"><a class="link" href="gobject-Closures.html#g-closure-add-marshal-guards" title="g_closure_add_marshal_guards ()">g_closure_add_marshal_guards</a></code> (invocation notification). There exist symmetric deregistration functions for finalization and invalidation events (<code class="function"><a class="link" href="gobject-Closures.html#g-closure-remove-finalize-notifier" title="g_closure_remove_finalize_notifier ()">g_closure_remove_finalize_notifier</a></code> and <code class="function"><a class="link" href="gobject-Closures.html#g-closure-remove-invalidate-notifier" title="g_closure_remove_invalidate_notifier ()">g_closure_remove_invalidate_notifier</a></code>) but not for the invocation process. <a href="#ftn.id-1.3.5.2.4.2.2.1.6" class="footnote" name="id-1.3.5.2.4.2.2.1.6"><sup class="footnote">[5]</sup></a></p></li> </ul></div> <p> </p> <div class="sect2"> <div class="titlepage"><div><div><h3 class="title"> <a name="id-1.3.5.2.5"></a>C Closures</h3></div></div></div> <p> If you are using C or C++ to connect a callback to a given event, you will either use simple <a class="link" href="gobject-Closures.html#GCClosure" title="struct GCClosure"><span class="type">GCClosure</span></a>s which have a pretty minimal API or the even simpler <code class="function"><a class="link" href="gobject-Signals.html#g-signal-connect" title="g_signal_connect()">g_signal_connect</a></code> functions (which will be presented a bit later). </p> <p> <code class="function"><a class="link" href="gobject-Closures.html#g-cclosure-new" title="g_cclosure_new ()">g_cclosure_new</a></code> will create a new closure which can invoke the user-provided callback_func with the user-provided <em class="parameter"><code>user_data</code></em> as its last parameter. When the closure is finalized (second stage of the destruction process), it will invoke the <em class="parameter"><code>destroy_data</code></em> function if the user has supplied one. </p> <p> <code class="function"><a class="link" href="gobject-Closures.html#g-cclosure-new-swap" title="g_cclosure_new_swap ()">g_cclosure_new_swap</a></code> will create a new closure which can invoke the user-provided <em class="parameter"><code>callback_func</code></em> with the user-provided <em class="parameter"><code>user_data</code></em> as its first parameter (instead of being the last parameter as with <code class="function"><a class="link" href="gobject-Closures.html#g-cclosure-new" title="g_cclosure_new ()">g_cclosure_new</a></code>). When the closure is finalized (second stage of the destruction process), it will invoke the <em class="parameter"><code>destroy_data</code></em> function if the user has supplied one. </p> </div> <div class="sect2"> <div class="titlepage"><div><div><h3 class="title"> <a name="id-1.3.5.2.6"></a>Non-C closures (for the fearless)</h3></div></div></div> <p> As was explained above, closures hide the details of callback invocation. In C, callback invocation is just like function invocation: it is a matter of creating the correct stack frame for the called function and executing a <span class="emphasis"><em>call</em></span> assembly instruction. </p> <p> C closure marshallers transform the array of GValues which represent the parameters to the target function into a C-style function parameter list, invoke the user-supplied C function with this new parameter list, get the return value of the function, transform it into a GValue and return this GValue to the marshaller caller. </p> <p> A generic C closure marshaller is available as <a class="link" href="gobject-Closures.html#g-cclosure-marshal-generic" title="g_cclosure_marshal_generic ()"><code class="function">g_cclosure_marshal_generic</code></a> which implements marshalling for all function types using libffi. Custom marshallers for different types are not needed apart from performance critical code where the libffi-based marshaller may be too slow. </p> <p> An example of a custom marshaller is given below, illustrating how <span class="type">GValue</span>s can be converted to a C function call. The marshaller is for a C function which takes an integer as its first parameter and returns void. </p> <div class="informalexample"> <table class="listing_frame" border="0" cellpadding="0" cellspacing="0"> <tbody> <tr> <td class="listing_lines" align="right"><pre>1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25</pre></td> <td class="listing_code"><pre class="programlisting"><span class="n">g_cclosure_marshal_VOID__INT</span> <span class="p">(</span><span class="n">GClosure</span> <span class="o">*</span><span class="n">closure</span><span class="p">,</span> <span class="n">GValue</span> <span class="o">*</span><span class="n">return_value</span><span class="p">,</span> <span class="n">guint</span> <span class="n">n_param_values</span><span class="p">,</span> <span class="k">const</span> <span class="n">GValue</span> <span class="o">*</span><span class="n">param_values</span><span class="p">,</span> <span class="n">gpointer</span> <span class="n">invocation_hint</span><span class="p">,</span> <span class="n">gpointer</span> <span class="n">marshal_data</span><span class="p">)</span> <span class="p">{</span> <span class="k">typedef</span> <span class="kt">void</span> <span class="p">(</span><span class="o">*</span><span class="n">GMarshalFunc_VOID__INT</span><span class="p">)</span> <span class="p">(</span><span class="n">gpointer</span> <span class="n">data1</span><span class="p">,</span> <span class="n">gint</span> <span class="n">arg_1</span><span class="p">,</span> <span class="n">gpointer</span> <span class="n">data2</span><span class="p">);</span> <span class="k">register</span> <span class="n">GMarshalFunc_VOID__INT</span> <span class="n">callback</span><span class="p">;</span> <span class="k">register</span> <span class="n">GCClosure</span> <span class="o">*</span><span class="n">cc</span> <span class="o">=</span> <span class="p">(</span><span class="n">GCClosure</span><span class="o">*</span><span class="p">)</span> <span class="n">closure</span><span class="p">;</span> <span class="k">register</span> <span class="n">gpointer</span> <span class="n">data1</span><span class="p">,</span> <span class="n">data2</span><span class="p">;</span> <span class="n">g_return_if_fail</span> <span class="p">(</span><span class="n">n_param_values</span> <span class="o">==</span> <span class="mi">2</span><span class="p">);</span> <span class="n">data1</span> <span class="o">=</span> <span class="n">g_value_peek_pointer</span> <span class="p">(</span><span class="n">param_values</span> <span class="o">+</span> <span class="mi">0</span><span class="p">);</span> <span class="n">data2</span> <span class="o">=</span> <span class="n">closure</span><span class="o">-></span><span class="n">data</span><span class="p">;</span> <span class="n">callback</span> <span class="o">=</span> <span class="p">(</span><span class="n">GMarshalFunc_VOID__INT</span><span class="p">)</span> <span class="p">(</span><span class="n">marshal_data</span> <span class="o">?</span> <span class="nl">marshal_data</span> <span class="p">:</span> <span class="n">cc</span><span class="o">-></span><span class="n">callback</span><span class="p">);</span> <span class="n">callback</span> <span class="p">(</span><span class="n">data1</span><span class="p">,</span> <span class="n">g_marshal_value_peek_int</span> <span class="p">(</span><span class="n">param_values</span> <span class="o">+</span> <span class="mi">1</span><span class="p">),</span> <span class="n">data2</span><span class="p">);</span> <span class="p">}</span></pre></td> </tr> </tbody> </table> </div> <p> </p> <p> There exist other kinds of marshallers, for example there is a generic Python marshaller which is used by all Python closures (a Python closure is used to invoke a callback written in Python). This Python marshaller transforms the input GValue list representing the function parameters into a Python tuple which is the equivalent structure in Python. </p> </div> </div> <div class="footnotes"> <br><hr style="width:100; text-align:left;margin-left: 0"> <div id="ftn.id-1.3.5.2.3.2" class="footnote"><p><a href="#id-1.3.5.2.3.2" class="para"><sup class="para">[4] </sup></a> In practice, closures sit at the boundary of language runtimes: if you are writing Python code and one of your Python callbacks receives a signal from a GTK+ widget, the C code in GTK+ needs to execute your Python code. The closure invoked by the GTK+ object invokes the Python callback: it behaves as a normal C object for GTK+ and as a normal Python object for Python code. </p></div> <div id="ftn.id-1.3.5.2.4.2.2.1.6" class="footnote"><p><a href="#id-1.3.5.2.4.2.2.1.6" class="para"><sup class="para">[5] </sup></a> Closures are reference counted and notify listeners of their destruction in a two-stage process: the invalidation notifiers are invoked before the finalization notifiers. </p></div> </div> </div> <div class="footer"> <hr>Generated by GTK-Doc V1.32</div> </body> </html>