| gdbus-codegen(1) | دستورات کاربر | gdbus-codegen(1) |
نام (NAME)
gdbus-codegen - تولیدکننده کدهای C و مستندات D-Bus
خلاصه دستور (SYNOPSIS)
gdbus-codegen [--help] [--interface-prefix org.project.Prefix] [--header | --body | --interface-info-header | --interface-info-body | --generate-c-code OUTFILES] [--c-namespace YourProject] [--c-generate-object-manager] [--c-generate-autocleanup none|objects|all] [--output-directory OUTDIR | --output OUTFILE] [--generate-docbook OUTFILES] [--generate-md OUTFILES] [--generate-rst OUTFILES] [--pragma-once] [--xml-files FILE] [--symbol-decorator DECORATOR [--symbol-decorator-header HEADER] [--symbol-decorator-define DEFINE]] [--annotate ELEMENT KEY VALUE]… [--glib-min-required VERSION] [--glib-max-allowed VERSION] [--extension-path EXTENSION_PATH] FILE…
توضیحات (DESCRIPTION)
دستور gdbus-codegen برای تولید کد و/یا مستندات برای یک یا چند رابط گذرگاه D-Bus به کار میرود.
دستور gdbus-codegen پروندههای XML دروننگری گذرگاه D-Bus https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format را از پروندههایی که به عنوان آرگومانهای خط فرمان ارسال شدهاند میخواند و پروندههای خروجی را تولید میکند. در حال حاضر از تولید کد مبدأ C (از طریق --body) یا سرایند (از طریق --header) و DocBook XML (از طریق --generate-docbook) پشتیبانی میکند. همچنین میتوان کدهای مبدأ و سرایندهای C محدودتری تولید کرد که فقط حاوی اطلاعات رابط (به عنوان ساختارهای GDBusInterfaceInfo) باشند که با استفاده از گزینههای --interface-info-body و --interface-info-header انجام میشود.
تولید کد C (GENERATING C CODE)
هنگام تولید کد C، یک نوع مشتقشده از GInterface برای هر رابط D-Bus تولید میشود. علاوه بر این، به ازای هر نوع تولیدشده، FooBar، دو نوع ملموس و قابل نمونهسازی با نامهای FooBarProxy و FooBarSkeleton که رابط مذکور را پیادهسازی میکنند نیز تولید میشوند. نوع اول از GDBusProxy مشتق شده و برای استفاده در سمت کلاینت در نظر گرفته شده است، در حالی که نوع دوم از نوع GDBusInterfaceSkeleton مشتق شده و برونریزی (export) آن را روی یک GDBusConnection چه مستقیماً و چه از طریق یک نمونه از GDBusObjectManagerServer آسان میسازد.
برای تولید کد C میتوان از --body (تولید کد مبدأ)، --header (تولید سرایندها)، --interface-info-body (تولید کد مبدأ اطلاعات رابط)، یا --interface-info-header (تولید سرایندهای اطلاعات رابط) استفاده کرد. این گزینهها باید همراه با --output استفاده شوند، که برای تعیین پرونده خروجی به کار میرود.
هر دو پرونده را میتوان به طور همزمان با استفاده از --generate-c-code تولید کرد، اما این گزینه منسوخ شده است. در این حالت به دلیل تولید چند پرونده نمیتوان از --output استفاده کرد؛ در عوض باید گزینه --output-directory را برای مشخص کردن پوشه/دایرکتوری خروجی مشخص کنید. به صورت پیشفرض پوشه فعلی استفاده خواهد شد.
نام هر نوع C تولیدشده از نام رابط D-Bus با حذف پیشوند ارائهشده توسط --interface-prefix، حذف نقطهها و بزرگ نوشتن حروف اول مشتق میشود. برای نمونه، برای رابط D-Bus با عنوان com.acme.Coyote، نام استفادهشده ComAcmeCoyote خواهد بود. برای رابط D-Bus با عنوان org.project.Bar.Frobnicator که مقدار --interface-prefix بر روی org.project. تنظیم شده است، نام استفادهشده BarFrobnicator خواهد بود.
برای متدها، سیگنالها و ویژگیها، در صورت مشخص نشدن، نام به صورت پیشفرض به نام همان متد، سیگنال یا ویژگی درمیآید.
دو شکل از نام استفاده میشود — شکل CamelCase و شکل حروف کوچک (lower-case). شکل CamelCase برای نامهای GType و ساختار به کار میرود، در حالی که شکل حروف کوچک در نام توابع به کار گرفته میشود. شکل حروف کوچک با تبدیل از CamelCase به حروف کوچک و درج خط زیر (underscore) در مرز کلمات (با استفاده از اصول هیوریستیک خاص) به دست میآید.
اگر مقدار ارائهشده توسط یادداشت org.gtk.GDBus.C.Name یا گزینه --c-namespace حاوی یک خط زیر باشد (که گاهی Ugly_Case نامیده میشود)، نام camel-case با حذف تمام خطهای زیر، و نام حروف کوچک با تبدیل کل رشته به حروف کوچک به دست میآید. این موضوع در برخی موارد که از کوتهنوشتها استفاده میشود مفید است. برای نمونه، اگر این یادداشت بر روی رابط net.MyCorp.MyApp.iSCSITarget با مقدار iSCSI_Target استفاده شود، شکل CamelCase آن iSCSITarget خواهد بود، در حالی که شکل حروف کوچک آن iscsi_target است. اگر یادداشت روی متد EjectTheiPod با مقدار Eject_The_iPod استفاده شود، شکل حروف کوچک eject_the_ipod خواهد بود.
تولید مستندات DOCBOOK (GENERATING DOCBOOK DOCUMENTATION)
هر پرونده DocBook XML تولیدشده (برای جزئیات به گزینه --generate-docbook نگاه کنید) یک مقاله RefEntry است که رابط D-Bus را توصیف میکند. (مستندات DocBook در https://tdg.docbook.org/tdg/4.5/refentry.html را ببینید.)
تولید مستندات MARKDOWN (GENERATING MARKDOWN DOCUMENTATION)
هر پرونده Markdown تولیدشده (برای جزئیات به گزینه --generate-md نگاه کنید) یک سند متنی ساده مارکداون است که رابط D-Bus را شرح میدهد.
تولید مستندات RESTRUCTUREDTEXT (GENERATING RESTRUCTUREDTEXT DOCUMENTATION)
هر پرونده reStructuredText تولیدشده (برای جزئیات به گزینه --generate-rst نگاه کنید) یک سند متنی ساده reStructuredText https://docutils.sourceforge.io/rst.html است که رابط D-Bus را شرح میدهد.
گزینهها (OPTIONS)
گزینههای زیر پشتیبانی میشوند:
-h, --help
--xml-files FILE
--interface-prefix org.project.Prefix.
--generate-docbook OUTFILES
برای تعیین پوشه/دایرکتوری قرارگیری پروندههای خروجی، گزینه --output-directory را پاس دهید. به صورت پیشفرض از پوشه فعلی استفاده خواهد شد.
--generate-md OUTFILES
برای تعیین پوشه/دایرکتوری قرارگیری پروندههای خروجی، گزینه --output-directory را پاس دهید. به صورت پیشفرض از پوشه فعلی استفاده خواهد شد.
--generate-rst OUTFILES
برای تعیین پوشه/دایرکتوری قرارگیری پروندههای خروجی، گزینه --output-directory را پاس دهید. به صورت پیشفرض از پوشه فعلی استفاده خواهد شد.
--generate-c-code OUTFILES
مسیرهای کامل در این صورت عبارت خواهند بود از: $(OUTDIR)/$(dirname $OUTFILES)/$(basename $OUTFILES).{c,h}.
--c-namespace YourProject
--pragma-once
--c-generate-object-manager
--c-generate-autocleanup none|objects|all
--output-directory OUTDIR
این گزینه را نمیتوان همراه با --body، --header، --interface-info-body یا --interface-info-header استفاده کرد؛ در این موارد باید از --output استفاده شود.
--header
استفاده از --generate-c-code، --generate-docbook یا --output-directory همراه با گزینههای --header و --body مجاز نیست، زیرا این گزینهها فقط برای تولید یک پرونده واحد استفاده میشوند.
--body
استفاده از --generate-c-code، --generate-docbook یا --output-directory همراه با گزینههای --header و --body مجاز نیست، زیرا این گزینهها فقط برای تولید یک پرونده واحد استفاده میشوند.
--interface-info-header
استفاده از --generate-c-code، --generate-docbook یا --output-directory همراه با گزینههای --interface-info-header و --interface-info-body مجاز نیست، زیرا این گزینهها برای تولید تنها یک پرونده استفاده میشوند.
--interface-info-body
استفاده از --generate-c-code، --generate-docbook یا --output-directory همراه با گزینههای --interface-info-header و --interface-info-body مجاز نیست، زیرا این گزینهها برای تولید تنها یک پرونده استفاده میشوند.
--symbol-decorator DECORATOR
این گزینه در GLib 2.66 اضافه شد.
--symbol-decorator-header HEADER
این گزینه در GLib 2.66 اضافه شد.
این گزینه تنها زمانی قابل استفاده است که از --symbol-decorator استفاده شده باشد.
--symbol-decorator-define DEFINE
این گزینه در GLib 2.66 اضافه شد.
این گزینه تنها زمانی قابل استفاده است که از --symbol-decorator استفاده شده باشد.
--output OUTFILE
استفاده از گزینههای --generate-c-code، --generate-docbook یا --output-directory در کنار --output مجاز نیست، زیرا مورد اخیر فقط برای تولید یک پرونده به کار میرود.
از نسخه GLib 2.80، اگر OUTFILE رشته دقیق - باشد، سرایند یا کد مبدأ به خروجی استاندارد نوشته میشود.
برای --body و --interface-info-body، کد تولیدشده هنگام نوشتن در خروجی استاندارد به طور خودکار پرونده سرایند متناظر را #include نخواهد کرد، چرا که نام مشخصی برای آن پرونده سرایند وجود ندارد. این امر ممکن است استفاده از cc -include foo.h یا تولید پروندهای مانند foo-impl.h و #include کردن آن در یک پرونده پوششی .c را ضروری کند.
برای --header و --interface-info-header، هیچ نام مشخصی برای محافظ شمول سنتی هنگام ارسال به خروجی استاندارد وجود ندارد، بنابراین استفاده از گزینه --pragma-once توصیه میشود.
در وضعیتهای نادری که نام پرونده خروجی مورد نظر با - آغاز شود، باید پیشوند ./ به آن افزوده شود.
--annotate ELEMENT KEY VALUE
gdbus-codegen --c-namespace MyApp \
--generate-c-code myapp-generated \
--annotate "org.project.InterfaceName" \
org.gtk.GDBus.C.Name MyFrobnicator \
--annotate "org.project.InterfaceName:Property" \
bar bat \
--annotate "org.project.InterfaceName.Method()" \
org.freedesktop.DBus.Deprecated true \
--annotate "org.project.InterfaceName.Method()[arg_name]" \
snake hiss \
--annotate "org.project.InterfaceName::Signal" \
cat meow \
--annotate "org.project.InterfaceName::Signal[arg_name]" \
dog wuff \
myapp-dbus-interfaces.xml
هر رشته UTF-8 میتواند برای KEY و VALUE استفاده شود.
--glib-min-required VERSION
توجه داشته باشید که برخی پارامترهای نسخه تغییرات ناسازگار ایجاد میکنند: ممکن است لازم باشد تمام فراخوانهای کد تولیدشده بهروزرسانی شوند، و اگر کد تولیدشده بخشی از API یا ABI یک کتابخانه باشد، افزایش پارامتر نسخه میتواند باعث شکستن API یا ABI شود.
شماره نسخه باید به شکل MAJOR.MINOR.MICRO باشد که تمام بخشهای آن اعداد صحیح هستند. بخشهای MINOR و MICRO اختیاری هستند. شماره نسخه نمیتواند کوچکتر از 2.30 باشد.
اگر شماره نسخه 2.64 یا بالاتر باشد، کد تولیدشده دارای ویژگیهای زیر خواهد بود:
- 1.
- اگر متدی دارای پارامتر(های) h (توصیفکننده پرونده) باشد، پارامتر GUnixFDList در کد تولیدشده برای آن وجود خواهد داشت (در حالی که قبلاً یادداشت org.gtk.GDBus.C.UnixFD لازم بود)، و
- 2.
- توابع فراخوانی متد دارای دو آرگومان اضافه خواهند بود تا به کاربر امکان دهند GDBusCallFlags و مقدار مهلت زمانی (timeout) را مشخص کند، همانطور که هنگام استفاده از g_dbus_proxy_call() امکانپذیر است.
--glib-max-allowed VERSION
شماره نسخه باید به شکل MAJOR.MINOR.MICRO باشد که در آن تمام بخشها اعداد صحیح هستند. بخشهای MINOR و MICRO اختیاری هستند. شماره نسخه باید بزرگتر یا مساوی با مقدار ارسالی به --glib-min-required باشد. به صورت پیشفرض مقدار آن برابر با نسخه GLib ارائهدهنده این gdbus-codegen است.
--extension-path EXTENSION_PATH
تمام دیگر رابطهای برنامهنویسی (API) که افزونه میتواند استفاده کند داخلی بوده و بنابراین ناپایدارند، اما تلاش میشود با تغییر این موارد داخلی، فیلد version افزایش یابد. در صورتی که تمایل به استفاده از این سازوکار دارید، لطفاً با ثبت یک گزارش در https://gitlab.gnome.org/GNOME/glib/-/issues مورد کاربردی خود را با ما در میان بگذارید.
یادداشتهای D-BUS پشتیبانیشده (SUPPORTED D-BUS ANNOTATIONS)
یادداشتهای D-Bus زیر توسط gdbus-codegen پشتیبانی میشوند:
org.freedesktop.DBus.Deprecated
هنگام تولید کد C، این یادداشت برای اضافه کردن ماکروی G_GNUC_DEPRECATED به توابع تولیدشده برای آن عنصر به کار میرود.
هنگام تولید DocBook XML، یک هشدار منسوخشدگی در کنار مستندات آن عنصر پدیدار خواهد شد.
org.gtk.GDBus.Since
هنگام تولید کد C، این فیلد برای اطمینان از ترتیب اشارهگرهای توابع جهت حفظ سازگاری ABI/API استفاده میشود؛ بخش «تضمینهای پایداری» را ببینید.
هنگام تولید DocBook XML، مقدار این تگ در مستندات ظاهر میشود.
org.gtk.GDBus.DocString
org.gtk.GDBus.DocString.Short
org.gtk.GDBus.C.Name
org.gtk.GDBus.C.ForceGVariant
org.gtk.GDBus.C.UnixFD
به عنوان راهکاری سادهتر به جای استفاده از یادداشت org.gtk.GDBus.DocString، توجه داشته باشید که تجزیهکننده مورد استفاده توسط gdbus-codegen یادداشتهای توضیحی XML را به روشی مشابه gtk-doc https://gitlab.gnome.org/GNOME/gtk-doc تجزیه میکند:
<!--
net.Corp.Bar:
@short_description: A short description
A <emphasis>longer</emphasis> description.
This is a new paragraph.
-->
<interface name="net.corp.Bar">
<!--
FooMethod:
@greeting: The docs for greeting parameter.
@response: The docs for response parameter.
The docs for the actual method.
-->
<method name="FooMethod">
<arg name="greeting" direction="in" type="s"/>
<arg name="response" direction="out" type="s"/>
</method>
<!--
BarSignal:
@blah: The docs for blah parameter.
@boo: The docs for boo parameter.
@since: 2.30
The docs for the actual signal.
-->
<signal name="BarSignal">
<arg name="blah" type="s"/>
<arg name="boo" type="s"/>
</signal>
<!-- BazProperty: The docs for the property. -->
<property name="BazProperty" type="s" access="read"/>
</interface>
توجه داشته باشید که @since میتواند در هر بخش از مستندات درونخطی (مثلاً برای رابطها، متدها، سیگنالها و ویژگیها) جهت تنظیم یادداشت org.gtk.GDBus.Since استفاده شود. برای یادداشت org.gtk.GDBus.DocString (و توضیحات درونخطی)، دقت کنید که زیررشتههایی به شکل #net.Corp.Bar، net.Corp.Bar.FooMethod()، #net.Corp.Bar::BarSignal و #net.Corp.InlineDocs:BazProperty همگی به پیوندهایی به رابط، متد، سیگنال و ویژگی مربوطه گسترش مییابند. علاوه بر این، زیررشتههایی که با کاراکترهای @ و % آغاز میشوند به ترتیب به صورت پارامتر https://tdg.docbook.org/tdg/4.5/parameter.html و ثوابت https://tdg.docbook.org/tdg/4.5/constant.html رندر میشوند.
اگر هر دو مورد توضیحات XML و یادداشتهای org.gtk.GDBus.DocString یا org.gtk.GDBus.DocString.Short وجود داشته باشند، اولویت با یادداشتها خواهد بود.
مثال (EXAMPLE)
پرونده XML دروننگری گذرگاه D-Bus زیر را در نظر بگیرید:
<node>
<interface name="net.Corp.MyApp.Frobber">
<method name="HelloWorld">
<arg name="greeting" direction="in" type="s"/>
<arg name="response" direction="out" type="s"/>
</method>
<signal name="Notification">
<arg name="icon_blob" type="ay"/>
<arg name="height" type="i"/>
<arg name="messages" type="as"/>
</signal>
<property name="Verbose" type="b" access="readwrite"/>
</interface>
</node>
اگر gdbus-codegen روی این پرونده به صورت زیر اجرا شود:
gdbus-codegen --generate-c-code myapp-generated \
--c-namespace MyApp \
--interface-prefix net.corp.MyApp. \
net.Corp.MyApp.Frobber.xml
دو پرونده به نامهای myapp-generated.[ch] تولید میشوند. این پروندهها یک نوع انتزاعی مشتقشده از GTypeInterface با نام MyAppFrobber و همچنین دو نوع قابل نمونهسازی با همان نام اما با پسوندهای Proxy و Skeleton ارائه میدهند. پرونده تولیدشده، به طور کلی، شامل امکانات زیر است:
/* GType macros for the three generated types */
#define MY_APP_TYPE_FROBBER (my_app_frobber_get_type ())
#define MY_APP_TYPE_FROBBER_SKELETON (my_app_frobber_skeleton_get_type ())
#define MY_APP_TYPE_FROBBER_PROXY (my_app_frobber_proxy_get_type ())
typedef struct _MyAppFrobber MyAppFrobber; /* Dummy typedef */
typedef struct
{
GTypeInterface parent_iface;
/* Signal handler for the ::notification signal */
void (*notification) (MyAppFrobber *proxy,
GVariant *icon_blob,
gint height,
const gchar* const *messages);
/* Signal handler for the ::handle-hello-world signal */
gboolean (*handle_hello_world) (MyAppFrobber *proxy,
GDBusMethodInvocation *invocation,
const gchar *greeting);
} MyAppFrobberIface;
/* Asynchronously calls HelloWorld() */
void
my_app_frobber_call_hello_world (MyAppFrobber *proxy,
const gchar *greeting,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean
my_app_frobber_call_hello_world_finish (MyAppFrobber *proxy,
gchar **out_response,
GAsyncResult *res,
GError **error);
/* Synchronously calls HelloWorld(). Blocks calling thread. */
gboolean
my_app_frobber_call_hello_world_sync (MyAppFrobber *proxy,
const gchar *greeting,
gchar **out_response,
GCancellable *cancellable,
GError **error);
/* Completes handling the HelloWorld() method call */
void
my_app_frobber_complete_hello_world (MyAppFrobber *object,
GDBusMethodInvocation *invocation,
const gchar *response);
/* Emits the ::notification signal / Notification() D-Bus signal */
void
my_app_frobber_emit_notification (MyAppFrobber *object,
GVariant *icon_blob,
gint height,
const gchar* const *messages);
/* Gets the :verbose GObject property / Verbose D-Bus property.
* Does no blocking I/O.
*/
gboolean my_app_frobber_get_verbose (MyAppFrobber *object);
/* Sets the :verbose GObject property / Verbose D-Bus property.
* Does no blocking I/O.
*/
void my_app_frobber_set_verbose (MyAppFrobber *object,
gboolean value);
/* Gets the interface info */
GDBusInterfaceInfo *my_app_frobber_interface_info (void);
/* Creates a new skeleton object, ready to be exported */
MyAppFrobber *my_app_frobber_skeleton_new (void);
/* Client-side proxy constructors.
*
* Additionally, _new_for_bus(), _new_for_bus_finish() and
* _new_for_bus_sync() proxy constructors are also generated.
*/
void
my_app_frobber_proxy_new (GDBusConnection *connection,
GDBusProxyFlags flags,
const gchar *name,
const gchar *object_path,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data);
MyAppFrobber *
my_app_frobber_proxy_new_finish (GAsyncResult *res,
GError **error);
MyAppFrobber *
my_app_frobber_proxy_new_sync (GDBusConnection *connection,
GDBusProxyFlags flags,
const gchar *name,
const gchar *object_path,
GCancellable *cancellable,
GError **error);
بنابراین، به ازای هر متد D-Bus، سه تابع C برای فراخوانی متد، یک سیگنال GObject برای مدیریت فراخوانی ورودی و یک تابع C برای تکمیل فراخوانی ورودی وجود خواهد داشت. به ازای هر سیگنال D-Bus، یک سیگنال GObject و یک تابع C برای ارسال آن وجود دارد. به ازای هر ویژگی D-Bus، دو تابع C (یکی setter و دیگری getter) و یک ویژگی GObject تولید میشود. جدول زیر امکانات تولیدشده و محل کاربرد آنها را خلاصه میکند:
| نوع نماد | کلاینت | سرور |
| انواع (Types) | استفاده از MyAppFrobberProxy. | هر نوعی که رابط MyAppFrobber را پیادهسازی کند. |
| متدها (Methods) | استفاده از m_a_f_hello_world() برای فراخوانی. | دریافت از طریق گرداننده سیگنال handle_hello_world(). تکمیل فراخوانی با m_a_f_complete_hello_world(). |
| سیگنالها (Signals) | اتصال به سیگنال ::notification. | استفاده از m_a_f_emit_notification() برای ارسال سیگنال. |
| ویژگیها (خواندن) | استفاده از m_a_f_get_verbose() یا ویژگی :verbose. | پیادهسازی تابع مجازی get_property() در GObject. |
| ویژگیها (نوشتن) | استفاده از m_a_f_set_verbose() یا ویژگی :verbose. | پیادهسازی تابع مجازی set_property() در GObject. |
استفاده در سمت کلاینت (Client-side usage)
شما میتوانید از نوع پراکسی تولیدشده همراه با سازندههای تولیدشده استفاده کنید:
MyAppFrobber *proxy;
GError *error;
error = NULL;
proxy = my_app_frobber_proxy_new_for_bus_sync (
G_BUS_TYPE_SESSION,
G_DBUS_PROXY_FLAGS_NONE,
"net.Corp.MyApp", /* bus name */
"/net/Corp/MyApp/SomeFrobber", /* object */
NULL, /* GCancellable* */
&error);
/* do stuff with proxy */
g_object_unref (proxy);
به جای استفاده از امکانات عمومی GDBusProxy، میتوان از متدهای تولیدشده مانند my_app_frobber_call_hello_world() برای فراخوانی متد D-Bus با نام net.Corp.MyApp.Frobber.HelloWorld() استفاده کرد، به سیگنال GObject با عنوان ::notification برای دریافت سیگنال D-Bus با نام net.Corp.MyApp.Frobber::Notification متصل شد و ویژگی D-Bus با نام net.Corp.MyApp.Frobber:Verbose را با استفاده از ویژگی :verbose در GObject یا متدهای my_app_get_verbose() و my_app_set_verbose() دریافت کرد یا مقدار داد. برای گوش فرا دادن به تغییرات ویژگیها، از سیگنال استاندارد GObject::notify استفاده کنید.
توجه داشته باشید که تمام دسترسیها به ویژگیها از طریق حافظه نهان (cache) ویژگی GDBusProxy انجام میشود، بنابراین هنگام خواندن ویژگیها هیچ عملیات I/O انجام نمیگیرد. همچنین توجه داشته باشید که تنظیم یک ویژگی باعث فراخوانی متد org.freedesktop.DBus.Properties.Set (مستندات https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties) بر روی شیء دوردست (remote) میشود. با این حال، این فراخوانی ناهمگام (asynchronous) است، بنابراین مقداردهی ویژگی مسدودکننده (blocking) نخواهد بود. علاوه بر این، اعمال تغییر با تأخیر همراه است و امکان بررسی خطا وجود ندارد.
استفاده در سمت سرور (Server-side usage)
رابط تولیدشده MyAppFrobber به گونهای طراحی شده است که پیادهسازی آن در یک زیرکلاس از GObject ساده باشد. برای نمونه، جهت رسیدگی به فراخوانیهای متد HelloWorld()، تابع مجازی handle_hello_world() را در ساختار MyAppFrobberIface تنظیم کنید. به طور مشابه، جهت رسیدگی به ویژگی net.Corp.MyApp.Frobber:Verbose، ویژگی :verbose در GObject را از زیرکلاس بازنویسی (override) نمایید. برای ارسال یک سیگنال، مثلاً از my_app_emit_signal() یا g_signal_emit_by_name() استفاده کنید.
به جای ایجاد زیرکلاس، اغلب سادهتر است که از زیرکلاس تولیدشده MyAppFrobberSkeleton استفاده کنید. برای مدیریت فراخوانیهای متد ورودی، از g_signal_connect() با سیگنالهای ::handle-* استفاده کنید و به جای بازنویسی توابع مجازی get_property() و set_property() از GObject، توابع g_object_get() و g_object_set() یا گترها و سترهای ویژگیهای تولیدشده را به کار ببرید (کلاس تولیدشده دارای یک پیادهسازی داخلی از بسته ویژگیها است).
برای مثال:
static gboolean
on_handle_hello_world (MyAppFrobber *interface,
GDBusMethodInvocation *invocation,
const gchar *greeting,
gpointer user_data)
{
if (g_strcmp0 (greeting, "Boo") != 0)
{
gchar *response;
response = g_strdup_printf ("Word! You said ‘%s’.", greeting);
my_app_complete_hello_world (interface, invocation, response);
g_free (response);
}
else
{
g_dbus_method_invocation_return_error (invocation,
MY_APP_ERROR,
MY_APP_ERROR_NO_WHINING,
"Hey, %s, there will be no whining!",
g_dbus_method_invocation_get_sender (invocation));
}
return TRUE;
}
[…]
interface = my_app_frobber_skeleton_new ();
my_app_frobber_set_verbose (interface, TRUE);
g_signal_connect (interface,
"handle-hello-world",
G_CALLBACK (on_handle_hello_world),
some_user_data);
[…]
error = NULL;
if (!g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (interface),
connection,
"/path/of/dbus_object",
&error))
{
/* handle error */
}
برای تسهیل تغییرات دستهای و اتمیک (تغییر چند ویژگی به طور همزمان)، سیگنالهای GObject::notify هنگام دریافت در صف قرار میگیرند. این صف در یک رسیدگیکننده بیکار (idle handler که از حلقه اصلی پیشفرض ریسه سازنده شیء اسکلتون فراخوانی میشود) تخلیه میشود و باعث ارسال سیگنال org.freedesktop.DBus.Properties::PropertiesChanged (مستندات https://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties) به همراه تمام ویژگیهای تغییر یافته خواهد شد. برای خالی کردن فوری صف، از g_dbus_interface_skeleton_flush() یا g_dbus_object_skeleton_flush() استفاده کنید. چنانچه روی ریسه (thread) دیگری هستید، برای اعمال تغییرات اتمیک از g_object_freeze_notify() و g_object_thaw_notify() استفاده کنید.
نگاشت انواع داده C (C TYPE MAPPING)
انواع اسکالر (رشتههای نوع b، y، n، q، i، u، x، t و d)، رشتهها (رشتههای نوع s، ay، o و g) و آرایههای رشتهای (رشتههای نوع as، ao و aay) به انواع طبیعی نگاشت میشوند، مانند gboolean، gdouble، gint، gchar*، gchar** و غیره. هر چیز دیگری به نوع GVariant نگاشت میگردد.
این نگاشت خودکار را میتوان با استفاده از یادداشت org.gtk.GDBus.C.ForceGVariant غیرفعال کرد — در صورت استفاده، همواره به جای نوع بومی متناظر در C، یک GVariant مبادله میشود. این یادداشت ممکن است هنگام استفاده از رشتههای بایتی (رشته نوع ay) برای دادههایی که ممکن است دارای بایتهای تهی (nul bytes) توکار باشند، مفید باشد.
تضمینهای پایداری (STABILITY GUARANTEES)
توابع C تولیدشده تضمین میشوند که ABI خود را تغییر ندهند. بدین معنا که اگر یک متد، سیگنال یا ویژگی امضای خود را در XML دروننگری تغییر ندهد، توابع C تولیدشده نیز ABI زبان C خود را تغییر نخواهند داد. ساختار کلاس و نمونههای تولیدشده نیز حفظ خواهد شد.
سازگاری ABI نمونههای GType تولیدشده تنها در صورتی حفظ خواهد شد که یادداشت org.gtk.GDBus.Since با دقت و هوشمندانه استفاده شود — این امر به این دلیل است که VTable برای GInterface بر اشارهگرهای توابع برای گردانندههای سیگنال متکی است. به طور مشخص، اگر یک متد، ویژگی یا سیگنال D-Bus به رابط D-Bus اضافه شود، ABI نوع GInterface تولیدشده اگر و تنها اگر حفظ میشود که هر متد، ویژگی یا سیگنال اضافه شده با یادداشت org.gtk.GDBus.Since همراه با شماره نسخهای بالاتر از نسخههای پیشین نشانهگذاری شود.
کدهای C تولیدشده در حال حاضر با توضیحات و یادداشتهای gtk-doc https://gitlab.gnome.org/GNOME/gtk-doc و GObject Introspection https://gi.readthedocs.io/en/latest نشانهگذاری میشوند. چیدمان و محتوا ممکن است در آینده تغییر کند، بنابراین هیچ تضمینی در مورد کاربرد مواردی مانند SECTION و غیره داده نمیشود.
در حالی که انتظار نمیرود پروندههای DocBook تولیدشده برای رابطهای D-Bus تغییر کنند، در حال حاضر هیچ تضمینی داده نمیشود.
نکته مهم این است که کدهای تولیدشده نباید در سیستمهای کنترل نسخه ذخیره شوند و نباید در آرشیوهای توزیع کد مبدأ قرار گیرند.
گزارش خطاها (BUGS)
لطفاً گزارشهای خطا را به ردیاب خطاهای توزیع یا ردیاب خطاهای بالادستی در https://gitlab.gnome.org/GNOME/glib/issues/new ارسال فرمایید.
همچنین ببینید (SEE ALSO)
gdbus(1) <man:gdbus(1)>