{"id":3634,"date":"2018-09-03T11:05:19","date_gmt":"2018-09-03T11:05:19","guid":{"rendered":"http:\/\/www.colorwave.it\/blog\/?p=3634"},"modified":"2018-09-03T16:12:48","modified_gmt":"2018-09-03T16:12:48","slug":"comunicazione-fra-oggetti-con-interfaccia-operation_call","status":"publish","type":"post","link":"https:\/\/www.colorwave.it\/blog\/framework\/comunicazione-fra-oggetti-con-interfaccia-operation_call\/admin\/2018\/09\/","title":{"rendered":"Comunicazione fra oggetti con interfaccia OPERATION_CALL"},"content":{"rendered":"<p>In un vecchio post avevamo descritto<a href=\"https:\/\/www.colorwave.it\/blog\/framework\/linterfaccia-operation_call\/admin\/2015\/05\/\">\u00a0 l&#8217;interfaccia\u00a0OPERATION_CALL<\/a>;\u00a0 in questo articolo descriviamo un insieme di macro usate per semplificare la comunicazione fra oggetti dotati di questa interfaccia;<\/p>\n<p><span style=\"color: #333333;\">Le nuove funzionalit\u00e0, introdotte dalla versione 7 di Colibri, permettono di trasferire messaggi e dati fra oggetti usando la nuova classe <span style=\"color: #800000;\"><em>test_request<\/em><\/span>\u00a0(che in questa esposizione non \u00e8 necessario discutere).<\/span><\/p>\n<p><span style=\"color: #333333;\"> Per procedere nell&#8217;esposizione ricordiamo che nel framework Colibri sono definibili due tipi di oggetti\/widget: oggetti a visibilit\u00e0 globale e oggetti accessibili attraverso il pointer.<\/span><\/p>\n<h3>Oggetti visibili globalmente<\/h3>\n<p>Una istanza di una classe di interfaccia OPERATION_CALL\u00a0 (in genere WIDGET, ma non necessariamente)\u00a0 pu\u00f2 essere accessibile globalmente nell&#8217;applicazione attraverso una registrazione, in genere definita nel costruttore; In questo caso l&#8217;istanza dovr\u00e0 essere unica, cio\u00e8 registrata una sola volta, definendo un identificatore; ad esempio la classe\u00a0<span style=\"color: #800000;\">DOCK_edit_layout<\/span>, che deve essere visibile alle classi\u00a0<span style=\"color: #800000;\">LAYOUT_printing_page<\/span>, viene costruita in fase di inizializzazione del programma in un&#8217;unica istanza, assegnandogli\u00a0 l&#8217;identificatore\u00a0 _$dock_edit_layout (definita in\u00a0<em><span style=\"color: #800000;\">CLB_language.h<\/span><\/em>); il codice che segue ne mostra le modalit\u00e0 di registrazione:<\/p>\n<pre class=\"lang:default decode:true\">DOCK_edit_layout::DOCK_edit_layout(void)\r\n{\r\n\t$_init\r\n\t\t__register_global_object(_$dock_edit_layout)\r\n\r\n\t\t__on_signal_create(__on_create_window)\r\n\t\t__on_signal_end_create(__on_end__create_window)\r\n\t\t__on_signal_paint(__on_paint_wnd)\r\n\t\t__on_signal_resize(__on_resize_window)\r\n\r\n}\r\n<\/pre>\n<p>La macro\u00a0<span style=\"color: #800000;\">__register_global_object<\/span> garantisce la visibilit\u00e0 globale dell&#8217;istanza, rendendola accessibile mediante l&#8217;identificatore dock_edit_layout; si ribadisce che la classe deve avere un&#8217;unica istanza allocata;<\/p>\n<p><strong>Accesso ad istanze registrate globalmente:\u00a0<\/strong>Un oggetto registrato globalmente pu\u00f2 essere individuato mediante la macro\u00a0<span style=\"color: #800000;\">__get_global_object<\/span> definita in<em> CLB_language.h:<\/em><\/p>\n<pre class=\"lang:default decode:true\">#define __get_global_object(_obj_id,opcl_obj)  \t\tOPERATION_CALL *opcl_obj = OPERATION_CALL::Get_global_object(obj_id);\r\n<\/pre>\n<p>Gli oggetti visibili globalmente sono in genere utilizzati per ricevere e trasmettere messaggi ed altre informazioni associate;<\/p>\n<h3>Oggetti visibili localmente<\/h3>\n<p>Sono tutti gli oggetti di interfaccia OPERATION_CALL che il programmatore pu\u00f2 accedere attraverso il pointer dell&#8217;istanza, ad esempio un WIDGET definito localmente o ricevuto come puntatore da una funzione.<\/p>\n<p><!--nextpage-->Nel contesto d&#8217;uso, la comunicazione verso l&#8217;interfaccia OPERATION_CALL di un oggetto \u00e8 definita nel modo seguente:<\/p>\n<p><strong>func_name<\/strong> : \u00e8 una stringa che identifica un gruppo funzionale (raggruppamento riconosciuto, come vedremo, attraverso la macro <span style=\"color: #800000;\">__is_function<\/span> dal ricevente).<\/p>\n<p><strong>op_id<\/strong>: \u00e8 una stringa che, se richiesta, definisce un raggruppamento secondario (vedremo fra poco praticamente cosa significa..)<\/p>\n<p><strong>args<\/strong>: \u00e8 un numero qualunque di argomenti associati alla coppia (func_name, op_id) separati da una virgola;<\/p>\n<p>quindi un messaggio mandato ad un OPERATION_CALL \u00e8 nella\u00a0 forma:<\/p>\n<p style=\"text-align: center;\"><strong>(func_name,\u00a0<\/strong>[<strong>op_id], [args])<\/strong><\/p>\n<p>Ad esempio:<\/p>\n<p style=\"text-align: center;\"><em>(_$replace,_$recipe,rcp_ptr)<\/em><\/p>\n<p>pu\u00f2 essere una richiesta ad un oggetto\u00a0 per la sostituzione di una ricetta con rcp_ptr.<\/p>\n<p>Un altro esempio<\/p>\n<p style=\"text-align: center;\"><em>($destroy,$object, 4, obj_list)<\/em><\/p>\n<p>\u00e8 un modo per richiedere ad un oggetto la distruzione di 4 oggetti contenuti nella lista obj_list;<br \/>\n<!--nextpage--><br \/>\nPer mandare un messaggio e un insieme di parametri ad un oggetto globale \u00e8 necessaria la conoscenza del suo identificatore globale; la richiesta \u00e8 effettuata mediante la macro variadic <em><span style=\"color: #800000;\">__exec_global_fn<\/span><\/em> della quale si riporta la definizione:<\/p>\n<pre class=\"lang:default decode:true\">#define __exec_global_fn(...)  test_request::exec_global_fn( __VA_ARGS__,_$end) \r\n<\/pre>\n<ul>\n<li>Il primo argomento della macro \u00e8 sempre l&#8217;identificatore globale dell&#8217;oggetto destinazione<\/li>\n<li>Il secondo argomento \u00e8\u00a0<span style=\"color: #008000;\"><em>func_name<\/em><\/span><strong>, <\/strong>seguito eventualmente da\u00a0<span style=\"color: #008000;\"><em>op_id<\/em><\/span><\/li>\n<li>Seguono eventualmente un numero qualunque di argomenti passati.<\/li>\n<\/ul>\n<p>Un esempio reale \u00e8\u00a0 il seguente:<\/p>\n<p style=\"text-align: center;\">_<span style=\"color: #800000;\"><em>_exec_global_fn(_$dock_edit_layout,_$detach,_$document,doc);<\/em><\/span><\/p>\n<p><span style=\"color: #000000;\"><em>La macro richiede\u00a0 all&#8217;oggetto globale\u00a0_$dock_edit_layout di sconnettersi (_$detach) dal documento (_$document) puntato da doc; \u00e8 equivalente, nel linguaggio CLB_language del framework alla frase<\/em><\/span><\/p>\n<p style=\"text-align: center;\"><span style=\"color: #800000;\"><em>_$detach _$document doc from $dock_edit_layout<\/em><\/span><\/p>\n<p>Del linguaggio interpretato CLB_language\u00a0 di Colibri scriveremo in successivi post.<\/p>\n<p>Ovviamente il messaggio dovr\u00e0 poter essere interpretato dall&#8217;istanza di identificatore\u00a0<span style=\"color: #800000;\"><em>_$dock_edit_layout;\u00a0\u00a0<\/em><\/span>fra poco descriveremo come, in un esempio pratico.<\/p>\n<p><!--nextpage-->Come abbiamo scritto, un oggetto locale \u00e8 noto attraverso la sua istanza, cio\u00e8 un puntatore ad un oggetto di interfaccia OPERATION_CALL; in questo caso si usa la macro variadic __exec_obj_fn\u00a0 definita anch&#8217;essa in <em>CLB_language<\/em>.<em>h<\/em>:<\/p>\n<pre class=\"lang:default decode:true\">#define __exec_obj_fn(...)  test_request::exec_obj_fn(__VA_ARGS__,_$end)\r\n<\/pre>\n<p>In questo caso il primo argomento sar\u00e0 un puntatore <em>obj_ptr<\/em> all&#8217;oggetto chiamato, seguito dalla serie di argomenti definiti:<\/p>\n<p style=\"text-align: center;\"><strong>(obj_ptr, func_name,\u00a0<\/strong>[<strong>op_id], [args])<\/strong><\/p>\n<p>Ad esempio:<\/p>\n<pre class=\"lang:default decode:true\">..\r\n__arg_value ret = __exec_obj_fn(doc, _$create, _$color_table, _$mask, _$str-&gt;mask_name.Value(), _$str-&gt;mask_name.Value());\r\n..<\/pre>\n<p>Nel frammento di codice l&#8217;oggetto chiamato \u00e8 un SPECTRAL_IMAGE doc al quale si richiede di creare una tabella colori da una mask della quale \u00e8 indicato il nome ;<\/p>\n<p>Le macro\u00a0<em><span style=\"color: #800000;\">__exec_obj_fn<\/span><\/em> e\u00a0<em><span style=\"color: #800000;\">__exec_global_fn<\/span><\/em> rimandano un tipo\u00a0<span style=\"color: #800000;\"><em>__arg_value<\/em><\/span> (void *) definito dall&#8217;oggetto chiamato, e riconoscibile dal chiamante per operazioni successive; spesso il valore ritornato \u00e8 _$true o _$false, e l&#8217;individuazione di questi valori pu\u00f2 essere fatto usando le macro <span style=\"color: #800000;\"><em>__is_true<\/em><\/span> e\u00a0\u00a0<span style=\"color: #800000;\"><em>__is_false\u00a0<\/em><\/span>, come si vede nell&#8217;esempio reale tratto dal codice di Colibri:<\/p>\n<pre class=\"lang:default decode:true\">static void CREATE_TABLE(CLASS_STR)\r\n{\r\n\tDOC_MASK_LIST *list=IMG-&gt;GetMaskList();\r\n\tif (!list) return;\r\n\r\n\tfor (int i=0;i&lt;list-&gt;Num();i++) {\r\n\t\tMSK *msk=list-&gt;GetMask(i);\r\n\t\tif (msk-&gt;flags.GetBit(LY_SEL)) {\r\n\r\n\t\t\t__arg_value ret = __exec_obj_fn((OPERATION_CALL *)IMG, _$create, _$color_table, _$mask, msk-&gt;id.Value(), msk-&gt;id.Value());\r\n\t\t\t__is_true(ret)\r\n\t\t\t{\r\n\t\t\t\t........\r\n\t\t\t\t........\r\n\t\t\t}\r\n\t\t\treturn;\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p><!--nextpage-->Abbiamo descritto le modalit\u00e0 di trasmissione dei messaggi verso un oggetto (globale o locale) di interfaccia OPERATION_CALL; descriveremo ora la costruzione dei metodi nella classe ricevente per interpretare i messaggi.<\/p>\n<p><img decoding=\"async\" data-attachment-id=\"3308\" data-permalink=\"https:\/\/www.colorwave.it\/blog\/?attachment_id=3308\" data-orig-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2018\/03\/word-image-119.png?fit=24%2C24&amp;ssl=1\" data-orig-size=\"24,24\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"word-image\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2018\/03\/word-image-119.png?fit=24%2C24&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2018\/03\/word-image-119.png?fit=24%2C24&amp;ssl=1\" tabindex=\"0\" role=\"button\" class=\"alignleft size-full wp-image-3308\" src=\"https:\/\/i0.wp.com\/www.colorwave.it\/blog\/wp-content\/uploads\/2018\/03\/word-image-119.png?resize=24%2C24&#038;ssl=1\" alt=\"\" width=\"24\" height=\"24\" data-recalc-dims=\"1\" \/><strong>Un breve inciso:<\/strong> f<em>ino ad ora abbiamo genericamente scritto di messaggi trasferiti da un trasmettitore ad un ricevente; a questo punto potremmo dire che si tratta di una chiamata ad una funzione (<span style=\"color: #008000;\">func_name<\/span>) relativa ad un oggetto base (<span style=\"color: #008000;\">op_id<\/span>)\u00a0con una eventuale lista di argomenti (<span style=\"color: #008000;\">args<\/span>);questa osservazione servir\u00e0 per comprendere la sintassi di analisi (parser) del comando nella classe ricevente;<\/em><\/p>\n<p><strong><span style=\"color: #800000;\">__add_function_parser<\/span><\/strong>: dichiarazione dello slot di parsing delle funzioni\u00a0<em><span style=\"color: #008000;\">func_name.\u00a0<\/span><\/em><\/p>\n<p>Le classi OPERATION_CALL, come \u00e8 stato scritto<a href=\"https:\/\/www.colorwave.it\/blog\/framework\/linterfaccia-operation_call\/admin\/2015\/05\/\"> in precedenza<\/a>, per ricevere i messaggi usano una particolare dichiarazione, la\u00a0<em>__declare_slots, <\/em>che costituisce una lista di <em>__slot <\/em>ciascuno correlato ad un particolare messaggio; per attivare la gestione delle funzioni<em> (<span style=\"color: #008000;\">func_name<\/span>) <\/em>\u00e8 sufficiente inserire nella dichiarazione la macro<em>__add_function_parser:<\/em><\/p>\n<pre class=\"lang:default decode:true\" title=\"__add_function_parser\">__declare_slots\r\n\t{ OP_DISPLAY, DO_DISPLAY_PANEL },\r\n\t{ OP_CLOSE, DO_CLOSE_PANEL },\r\n\t{ OP_SWITCH, DO_SWITCH_PANEL },\r\n\r\n\t__add_function_parser\r\n\r\n__end__declare_slots\r\n<\/pre>\n<p>Nell&#8217;esempio appena riportato, estratto dal codice della classe\u00a0<em>DOCK_edit_layout<\/em> in Colibri, la macro <em>__add_function_parser<\/em> attiva automaticamente il riconoscimento dello slot\u00a0\u00a0<em>__slot_function_parser<\/em>, il cui scopo \u00e8 analizzare i messaggio ricevuti; il codice mostra l&#8217;uso di macro per il parsing del contenuto e forma dei messaggi:<\/p>\n<pre class=\"lang:default decode:true\" title=\"Parser dei messaggi\">\/\/ parser delle funzioni chiamate \r\n\/\/\r\n__slot_function_parser\r\n\r\n\t__is_function(_$detach)\r\n\t{\r\n\t\t__operation_case(_$document)\r\n\t\t{\r\n\t\t\t__pop_param(edit, LAYOUT_printing_page);\r\n\t\t\tif (!edit)\r\n\t\t\t{\r\n\t\t\t\t\t_$str-&gt;layout = 0;\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\tif (edit == _$str-&gt;layout)\r\n\t\t\t{\r\n\t\t\t\t_$str-&gt;layout = 0;\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t__is_function(_$display)\r\n\t{\r\n\t\t__operation_case(_$document)\r\n\t\t{\r\n\t\t\t__pop_param(edit, LAYOUT_printing_page);\r\n\t\t\tif (edit)\r\n\t\t\t{\r\n\t\t\t\tif (edit != _$str-&gt;layout)\r\n\t\t\t\t{\r\n\t\t\t\t\t_$str-&gt;layout = edit;\r\n\t\t\t\t\t__trace(L\"edit nuovo layout \")\r\n\t\t\t\t}\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\telse\t\t\/\/ rimosso layout\r\n\t\t\t{\r\n\t\t\t\t_$str-&gt;layout = 0;\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\r\n\t\t__operation_case(_$all)\r\n\t\t{\r\n\t\t\t_redisplay_document(_$str);\r\n\t\t}\r\n\r\n\t}\r\n\telse\r\n\t__is_function(_$remove)\r\n\t{\r\n\t\tif (!_$str-&gt;layout) return false;\r\n\r\n\t\t__operation_case(_$document)\r\n\t\t{\r\n\t\t\t__pop_param(doc, DOCUMENT)\r\n\t\t\t\t_$str-&gt;layout-&gt;RemoveDocumentObjects(doc);\r\n\t\t\t__panel_refresh(_$dock_edit_layout)\r\n\t\t}\r\n\t}\r\n\telse\r\n\t__is_function(_$resize)\r\n\t{\r\n\t\tif (!_$str-&gt;layout) return false;\r\n\r\n\t\t__operation_case(_$document)\r\n\t\t{\r\n\t\t\t__pop_param(doc, DOCUMENT)\r\n\t\t\t\t__pop_param(rect, RectF)\r\n\t\t\t\tRESIZE_SELECTED_DOCUMENT(_$str, doc, rect);\r\n\t\t\t\/\/__panel_refresh(_$dock_edit_layout)\r\n\t\t}\r\n\t}\r\n\telse\r\n\t__is_function(_$edit)\r\n\t{\r\n\t__operation_case(_$selected)\r\n\t\t{\r\n\t\t\t__pop_param(ly, LY_OBJECT)\r\n\t\t\t\tif (!ly) return false;\r\n\t\t\tEDIT_SELECTED_OBJECT(_$str, ly);\r\n\t\t}\r\n\t}\r\n\telse\r\n\t__is_function(_$copy)\r\n\t{\r\n\t__operation_case(_$selected)\r\n\t\t{\r\n\t\t\tif (_$str-&gt;layout)\r\n\t\t\t\t_$str-&gt;layout-&gt;CopySelectedToClipBoard();\r\n\t\t}\r\n}\r\n<\/pre>\n<p><!--nextpage-->Lo slot di ricezione dei messaggi \u00e8 definito all&#8217;interno del blocco<\/p>\n<p style=\"text-align: center;\"><span style=\"color: #800000;\"><em>__slot_function_parser\u00a0 &#8230;\u00a0 __end__declare_slots<\/em><\/span><\/p>\n<p>Per l&#8217;analisi dei messaggi sono definite un gruppo di macro che semplificano la navigazione nella struttura dati relativa:<\/p>\n<p><span style=\"color: #800000;\"><strong>__is_function<\/strong><\/span>: usata per il riconoscimento di una\u00a0 <em><span style=\"color: #008000;\">func_name<\/span><\/em> ; se riconoscita la\u00a0<em>func_name<\/em> viene eseguito il blocco<span style=\"color: #008000;\">\u00a0{ ..\u00a0}<\/span> che segue nel codice:<\/p>\n<pre class=\"lang:default decode:true\">__slot_function_parser\r\n\r\n\t__is_function(_$detach)\r\n\t{\r\n\t\t__operation_case(_$document)\r\n\t\t{\r\n\t\t\t__pop_param(edit, LAYOUT_printing_page);\r\n\t\t\tif (!edit)\r\n\t\t\t{\r\n\t\t\t\t\t_$str-&gt;layout = 0;\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\tif (edit == _$str-&gt;layout)\r\n\t\t\t{\r\n\t\t\t\t_$str-&gt;layout = 0;\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n        ....\r\n        ....\r\n__end_slot\r\n\r\n<\/pre>\n<p><span style=\"color: #800000;\"><strong>__operation_case<\/strong><\/span>: individuazione dell&#8217;argomento\u00a0<em><span style=\"color: #008000;\">op_id.\u00a0\u00a0<\/span><\/em>La macro \u00e8 usata all&#8217;interno del blocco <span style=\"color: #800000;\"><em><span style=\"color: #008000;\">__is_function; <\/span><\/em><\/span>se l&#8217;argomento passato alla macro \u00e8 quello atteso, viene definito un nuovo blocco per continuare l&#8217;analisi degli argomenti e\/o eseguire il codice successivo;<\/p>\n<p><span style=\"color: #800000;\"><strong>__pop_param<\/strong><\/span>: estrazione di un argomento tipizzato (<span style=\"color: #008000;\"><em>args<\/em><\/span>). la macro permette di istanziare un puntatore all&#8217;argomento successivo ricevuto; gli argomenti ricevuti sono tipizzati, pertanto la macro riceve due argomenti: il primo (nell&#8217;esempio, edit) \u00e8 il nome dell&#8217;istanza estratta; il secondo (nell&#8217;esempio\u00a0\u00a0LAYOUT_printing_page) \u00e8 la classe del tipo di istanza generata; la tipizzazione pu\u00f2 corrispondere ad uno dei tipi, strutture o classi standard di C++; La funzione deve essere richiamata nel blocco tante volte quante previste nel protocollo di comunicazione; nel nostro caso, tratto dalla classe <em><span style=\"color: #800000;\">DOCK_edit_layout<\/span><\/em>,\u00a0 \u00e8 presente un solo argomento (args), avendo interpretato il comando:<\/p>\n<p style=\"text-align: center;\"><span style=\"color: #800000;\">_<em>_exec_global_fn(_$dock_edit_layout,_$detach,_$document,doc);<\/em><\/span><\/p>\n<p>Valore ritornato dalla\u00a0<span style=\"color: #008000;\"><em>__slot_function_parser<\/em><\/span>: la funzione rimanda true o false ad indicare che il comando \u00e8 stato intercettato (true) o no (false); prima di ritornare al chiamante, \u00e8 possibile dichiarare un oggetto di ritorno per le macro\u00a0<span style=\"color: #008000;\"><em>__exec_global_fn<\/em><\/span> o\u00a0<span style=\"color: #008000;\"><em>__exec_obj_fn<\/em><\/span> usate dal chiamante, attraverso l&#8217;uso della macro\u00a0__return.<\/p>\n<p><!--nextpage-->il comando __return permette di rimandare un oggetto dopo la ricezione del messaggio; \u00e8 importante notare che utilizzando questi metodi di comunicazione fra gli oggetti non \u00e8 in genere necessario conoscerne la tipizzazione, nel caso di oggetti globali; questo permette di lanciare messaggi che non necessariamente saranno interpretati (ad esempio\u00a0 l&#8217;oggetto globale pu\u00f2 non esistere, o il comando non\u00a0 essere corretto, ma questo non generer\u00e0 eccezioni nel codice);\u00a0 l&#8217;oggetto globale pu\u00f2 essere definito in una DLL non direttamente accessibile (visibile) da quella chiamante.<\/p>\n<p><strong><span style=\"color: #800000;\">__return<\/span><\/strong>:\u00a0 all&#8217;interno del blocco di riconoscimento del comando \u00e8 possibile utilizzare la macro per restituire un oggetto; ad esempio:<\/p>\n<pre class=\"lang:default decode:true \">__is_function(_$export)\r\n     {\r\n\tif (__required_operation(_$lum)) \t\t\/\/ expor lum channel..\r\n        {\r\n\t  __return($obj-&gt;GetLuminanceMap())\r\n\t}\r\n        \/\/......\r\n        \/\/......\r\n        \/\/......\r\n    }\r\n    \/\/...<\/pre>\n<p>Il codice riportato riconosce il comando\u00a0 <span style=\"color: #008000;\"><em>(_$export,_$lum)\u00a0<\/em><\/span> \u00a0e usa la macro __return per rimandare il canale di luminanza generato sull&#8217;istanza SPECTRAL_IMAGE.<\/p>\n<p>Un possibile comando per ricevere questa informazione \u00e8 :<\/p>\n<pre class=\"lang:default decode:true\">DOCUMENT *doc = ( DOCUMENT * ) __exec_global_fn(spt_doc,\u00a0_$export,_$lum);\r\nif (doc)\r\n{\r\n  \/\/.....\r\n  \/\/.....\r\n}\r\n<\/pre>\n<p>Dove <em><span style=\"color: #008000;\">doc<\/span><\/em> \u00e8 il documento luminanza rimandato e <em><span style=\"color: #008000;\">spt_doc<\/span><\/em> \u00e8 l&#8217;oggetto SPECTRAL_IMAGE interrogato; notare che il valore ritornato \u00e8 caratterizzato come DOCUMENT.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In un vecchio post avevamo descritto\u00a0 l&#8217;interfaccia\u00a0OPERATION_CALL;\u00a0 in questo articolo descriviamo un insieme di macro usate per semplificare la comunicazione fra oggetti dotati di questa interfaccia; Le nuove funzionalit\u00e0, introdotte dalla versione 7 di Colibri, permettono di trasferire messaggi e dati fra&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"aside","meta":{"_acf_changed":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"footnotes":"","_jetpack_memberships_contains_paid_content":false,"jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[19,112],"tags":[113],"jetpack_publicize_connections":[],"acf":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9rwsf-WC","jetpack_likes_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts\/3634"}],"collection":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/comments?post=3634"}],"version-history":[{"count":6,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts\/3634\/revisions"}],"predecessor-version":[{"id":3641,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/posts\/3634\/revisions\/3641"}],"wp:attachment":[{"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/media?parent=3634"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/categories?post=3634"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.colorwave.it\/blog\/wp-json\/wp\/v2\/tags?post=3634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}