gdbus-codegen(1) دستورات کاربر gdbus-codegen(1)

gdbus-codegen - تولیدکننده کدهای C و مستندات D-Bus

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…

دستور 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، یک نوع مشتق‌شده از 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 XML تولیدشده (برای جزئیات به گزینه --generate-docbook نگاه کنید) یک مقاله RefEntry است که رابط D-Bus را توصیف می‌کند. (مستندات DocBook در https://tdg.docbook.org/tdg/4.5/refentry.html را ببینید.)

هر پرونده Markdown تولیدشده (برای جزئیات به گزینه --generate-md نگاه کنید) یک سند متنی ساده مارک‌داون است که رابط D-Bus را شرح می‌دهد.

هر پرونده reStructuredText تولیدشده (برای جزئیات به گزینه --generate-rst نگاه کنید) یک سند متنی ساده reStructuredText https://docutils.sourceforge.io/rst.html است که رابط D-Bus را شرح می‌دهد.

گزینه‌های زیر پشتیبانی می‌شوند:

-h, --help

نمایش پیام راهنما و خروج.

--xml-files FILE

این گزینه منسوخ شده است؛ به جای آن از آرگومان‌های مکانی استفاده کنید. پرونده XML درون‌نگری D-Bus.

--interface-prefix org.project.Prefix.

پیشوندی که باید هنگام محاسبه نام نوع برای پیوند C و ویژگی sortas در DocBook https://tdg.docbook.org/tdg/4.5/primary.html از ابتدای تمام نام‌های رابط D-Bus حذف شود.

--generate-docbook OUTFILES

تولید مستندات DocBook برای هر رابط D-Bus و قرار دادن آن در OUTFILES-NAME.xml که در آن NAME جایگاهی برای نام رابط است، مانند net.Corp.FooBar و غیره.

برای تعیین پوشه/دایرکتوری قرارگیری پرونده‌های خروجی، گزینه --output-directory را پاس دهید. به صورت پیشفرض از پوشه فعلی استفاده خواهد شد.

--generate-md OUTFILES

تولید مستندات مارک‌داون برای هر رابط D-Bus و قرار دادن آن در OUTFILES-NAME.md که در آن NAME جایگاهی برای نام رابط است، مانند net.Corp.FooBar و غیره.

برای تعیین پوشه/دایرکتوری قرارگیری پرونده‌های خروجی، گزینه --output-directory را پاس دهید. به صورت پیشفرض از پوشه فعلی استفاده خواهد شد.

--generate-rst OUTFILES

تولید مستندات reStructuredText برای هر رابط D-Bus و قرار دادن آن در OUTFILES-NAME.rst که در آن NAME جایگاهی برای نام رابط است، مانند net.Corp.FooBar و غیره.

برای تعیین پوشه/دایرکتوری قرارگیری پرونده‌های خروجی، گزینه --output-directory را پاس دهید. به صورت پیشفرض از پوشه فعلی استفاده خواهد شد.

--generate-c-code OUTFILES

تولید کد C برای تمام رابط‌های D-Bus و قرار دادن آن در OUTFILES.c و OUTFILES.h شامل هرگونه زیرپوشه. اگر می‌خواهید پرونده‌ها در مکان متفاوتی قرار گیرند از --output-directory استفاده کنید زیرا به OUTFILES.h (شامل زیرپوشه‌ها) از درون OUTFILES.c ارجاع داده خواهد شد.

مسیرهای کامل در این صورت عبارت خواهند بود از: $(OUTDIR)/$(dirname $OUTFILES)/$(basename $OUTFILES).{c,h}.

--c-namespace YourProject

فضای نام (Namespace) مورد استفاده برای کدهای C تولیدشده. انتظار می‌رود این مقدار به قالب CamelCase https://en.wikipedia.org/wiki/Camel_case یا Ugly_Case (توضیح داده شده در بالا) باشد.

--pragma-once

در صورت ارسال این گزینه، دستور پیش‌پردازنده #pragma once https://en.wikipedia.org/wiki/Pragma_once به جای محافظ‌های شمول (include guards) استفاده می‌شود.

--c-generate-object-manager

در صورت ارسال این گزینه، زیرکلاس‌های مناسب از GDBusObject، GDBusObjectProxy، GDBusObjectSkeleton و GDBusObjectManagerClient تولید می‌شوند.

--c-generate-autocleanup none|objects|all

این گزینه تعیین می‌کند که توابع پاکسازی خودکار (autocleanup) برای چه انواعی تولید شوند. مقدار none به معنای عدم تولید هیچ تابع پاکسازی خودکار است؛ objects به معنای تولید آن‌ها برای انواع اشیاء (object types) است و all به معنای تولید آن‌ها برای هم انواع اشیاء و هم رابط‌ها است. مقدار پیشفرض به دلیل سازگاری با موارد خاص در پروژه‌های قدیمی objects است، اما بهتر است پروژه خود را به استفاده از all تغییر دهید. این گزینه در GLib 2.50 اضافه شد.

--output-directory OUTDIR

پوشه/دایرکتوری خروجی کدهای مبدأ تولیدشده. معادل تغییر پوشه قبل از شروع تولید کد است.

این گزینه را نمی‌توان همراه با --body، --header، --interface-info-body یا --interface-info-header استفاده کرد؛ در این موارد باید از --output استفاده شود.

--header

اگر این گزینه داده شود، کد سرایند را تولید کرده و با استفاده از مسیر و نام پرونده مشخص‌شده توسط --output روی دیسک می‌نویسد.

استفاده از --generate-c-code، --generate-docbook یا --output-directory همراه با گزینه‌های --header و --body مجاز نیست، زیرا این گزینه‌ها فقط برای تولید یک پرونده واحد استفاده می‌شوند.

--body

اگر این گزینه داده شود، کد مبدأ را تولید کرده و با استفاده از مسیر و نام پرونده مشخص‌شده توسط --output روی دیسک می‌نویسد.

استفاده از --generate-c-code، --generate-docbook یا --output-directory همراه با گزینه‌های --header و --body مجاز نیست، زیرا این گزینه‌ها فقط برای تولید یک پرونده واحد استفاده می‌شوند.

--interface-info-header

اگر این گزینه داده شود، کد سرایند را فقط برای ساختارهای GDBusInterfaceInfo تولید کرده و با استفاده از مسیر و نام پرونده ارائه‌شده توسط --output بر روی دیسک ذخیره می‌کند.

استفاده از --generate-c-code، --generate-docbook یا --output-directory همراه با گزینه‌های --interface-info-header و --interface-info-body مجاز نیست، زیرا این گزینه‌ها برای تولید تنها یک پرونده استفاده می‌شوند.

--interface-info-body

اگر این گزینه داده شود، کد مبدأ را فقط برای ساختارهای GDBusInterfaceInfo تولید کرده و با استفاده از مسیر و نام پرونده ارائه‌شده توسط --output بر روی دیسک ذخیره می‌کند.

استفاده از --generate-c-code، --generate-docbook یا --output-directory همراه با گزینه‌های --interface-info-header و --interface-info-body مجاز نیست، زیرا این گزینه‌ها برای تولید تنها یک پرونده استفاده می‌شوند.

--symbol-decorator DECORATOR

چنانچه یک DECORATOR با این گزینه مشخص شود، تمامی پیش‌نمونه‌های توابع تولیدشده در سرایند با DECORATOR نشانه‌گذاری خواهند شد. این کار برای مثال جهت برون‌ریزی (export) نمادها از کدهای تولیدشده با gdbus-codegen کاربرد دارد.

این گزینه در GLib 2.66 اضافه شد.

--symbol-decorator-header HEADER

چنانچه یک HEADER با این گزینه مشخص شود، سرایند تولیدشده یک عبارت #include HEADER را قبل از بقیه موارد (به جز محافظ‌های شمول یا #pragma once در صورت استفاده از --pragma-once) قرار خواهد داد. این حالت زمانی کاربرد دارد که برای تعریف دکوراتور مشخص‌شده با --symbol-decorator، گنجاندن پرونده سرایند دیگری لازم باشد.

این گزینه در GLib 2.66 اضافه شد.

این گزینه تنها زمانی قابل استفاده است که از --symbol-decorator استفاده شده باشد.

--symbol-decorator-define DEFINE

چنانچه یک DEFINE با این گزینه مشخص شود، کد مبدأ تولیدشده عبارت #define DEFINE را پیش از سایر موارد اضافه خواهد کرد. این حالت زمانی استفاده می‌شود که ماکروی خاصی لازم باشد تا اطمینان حاصل شود دکوراتور داده‌شده از طریق --symbol-decorator هنگام کامپایل کد مبدأ از تعریف درستی استفاده می‌کند.

این گزینه در GLib 2.66 اضافه شد.

این گزینه تنها زمانی قابل استفاده است که از --symbol-decorator استفاده شده باشد.

--output OUTFILE

مسیر کاملی که سرایند (--header، --interface-info-header) یا کد مبدأ (--body، --interface-info-body) با استفاده از مسیر و نام پرونده مشخص‌شده توسط --output در آن نوشته می‌شود. مسیر کامل می‌تواند چیزی شبیه به $($OUTFILE).{c,h} باشد.

استفاده از گزینه‌های --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

برای تزریق یادداشت‌های D-Bus به پرونده‌های XML داده‌شده استفاده می‌شود. می‌توان از آن به شیوه زیر برای رابط‌ها، متدها، سیگنال‌ها، ویژگی‌ها و آرگومان‌ها استفاده کرد:
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

حداقل نسخه GLib را مشخص می‌کند که کد تولیدشده توسط gdbus-codegen می‌تواند به آن وابسته باشد. از این گزینه می‌توان برای ایجاد تغییرات ناسازگار با گذشته در خروجی یا رفتار gdbus-codegen در آینده استفاده کرد، که کاربران با افزایش مقدار ارسالی برای --glib-min-required می‌توانند آن را فعال سازند. اگر این گزینه پاس داده نشود، سازگاری خروجی gdbus-codegen با تمام نسخه‌های GLib از 2.30 به بالا تضمین می‌شود، زیرا نخستین بار gdbus-codegen در این نسخه منتشر شد.

توجه داشته باشید که برخی پارامترهای نسخه تغییرات ناسازگار ایجاد می‌کنند: ممکن است لازم باشد تمام فراخوان‌های کد تولیدشده به‌روزرسانی شوند، و اگر کد تولیدشده بخشی از 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

حداکثر نسخه GLib را مشخص می‌کند که کد تولیدشده توسط gdbus-codegen می‌تواند به آن وابسته باشد. از این گزینه می‌توان اطمینان حاصل کرد که کدهای تولیدشده توسط gdbus-codegen با نسخه‌های قدیمی‌تر خاص GLib که نرم‌افزار شما باید از آن‌ها پشتیبانی کند قابل کامپایل باشند.

شماره نسخه باید به شکل MAJOR.MINOR.MICRO باشد که در آن تمام بخش‌ها اعداد صحیح هستند. بخش‌های MINOR و MICRO اختیاری هستند. شماره نسخه باید بزرگتر یا مساوی با مقدار ارسالی به --glib-min-required باشد. به صورت پیشفرض مقدار آن برابر با نسخه GLib ارائه‌دهنده این gdbus-codegen است.

--extension-path EXTENSION_PATH

برای بارگذاری یک افزونه در codegen استفاده می‌شود. شناسه EXTENSION_PATH مسیری به یک پرونده پایتون است که به عنوان ماژول بارگذاری خواهد شد. این افزونه باید دست‌کم تابع def init(args, options) را تعریف کند که در آن args یک argparse.Namespace و options یک فرهنگ‌لغت حاوی کلید version است.

تمام دیگر رابط‌های برنامه‌نویسی (API) که افزونه می‌تواند استفاده کند داخلی بوده و بنابراین ناپایدارند، اما تلاش می‌شود با تغییر این موارد داخلی، فیلد version افزایش یابد. در صورتی که تمایل به استفاده از این سازوکار دارید، لطفاً با ثبت یک گزارش در https://gitlab.gnome.org/GNOME/glib/-/issues مورد کاربردی خود را با ما در میان بگذارید.

یادداشت‌های D-Bus زیر توسط gdbus-codegen پشتیبانی می‌شوند:

org.freedesktop.DBus.Deprecated

می‌تواند روی هر عنصر <interface>، <method>، <signal> و <property> استفاده شود تا در صورتی که مقدار آن true باشد، منسوخ بودن آن عنصر را مشخص سازد. توجه داشته باشید که این یادداشت در مشخصات گذرگاه D-Bus https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format تعریف شده است و تنها می‌تواند مقادیر true و false را بپذیرد. به طور خاص، شما نمی‌توانید نسخه‌ای که عنصر در آن منسوخ شده یا پیامی توضیحی برای منسوخ شدن مشخص کنید؛ چنین اطلاعاتی باید در مستندات عنصر درج شوند.

هنگام تولید کد C، این یادداشت برای اضافه کردن ماکروی G_GNUC_DEPRECATED به توابع تولیدشده برای آن عنصر به کار می‌رود.

هنگام تولید DocBook XML، یک هشدار منسوخ‌شدگی در کنار مستندات آن عنصر پدیدار خواهد شد.

org.gtk.GDBus.Since

می‌تواند روی هر عنصر <interface>، <method>، <signal> و <property> به کار رود تا نسخه‌ای را که عنصر در آن پدیدار شده است مشخص کند (هر رشته با قالب آزاد اما با تابعی آگاه از نسخه مقایسه می‌شود).

هنگام تولید کد C، این فیلد برای اطمینان از ترتیب اشاره‌گرهای توابع جهت حفظ سازگاری ABI/API استفاده می‌شود؛ بخش «تضمین‌های پایداری» را ببینید.

هنگام تولید DocBook XML، مقدار این تگ در مستندات ظاهر می‌شود.

org.gtk.GDBus.DocString

رشته‌ای حاوی محتوای DocBook برای مستندسازی. این یادداشت می‌تواند روی عناصر <interface>، <method>، <signal>، <property> و <arg> استفاده شود.

org.gtk.GDBus.DocString.Short

رشته‌ای با محتوای DocBook برای مستندسازی کوتاه و مختصر. این یادداشت تنها روی عناصر <interface> قابل استفاده است.

org.gtk.GDBus.C.Name

می‌تواند روی هر عنصر <interface>، <method>، <signal> و <property> استفاده شود تا نام مورد استفاده در هنگام تولید کد C را مشخص کند. مقدار آن باید به شکل CamelCase https://en.wikipedia.org/wiki/Camel_case یا Ugly_Case (توضیح داده شده در بالا) باشد.

org.gtk.GDBus.C.ForceGVariant

در صورت تنظیم بر روی یک رشته غیرخالی، به جای نوع طبیعی C از یک نمونه GVariant استفاده خواهد شد. این یادداشت می‌تواند روی هر عنصر <arg> و <property> استفاده شود.

org.gtk.GDBus.C.UnixFD

در صورت تنظیم بر روی یک رشته غیرخالی، کد تولیدشده شامل پارامترهایی برای تبادل توصیف‌کننده‌های پرونده با استفاده از نوع GUnixFDList خواهد بود. این یادداشت می‌تواند روی عناصر <method> استفاده شود.

به عنوان راهکاری ساده‌تر به جای استفاده از یادداشت 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 وجود داشته باشند، اولویت با یادداشت‌ها خواهد بود.

پرونده 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.

شما می‌توانید از نوع پراکسی تولیدشده همراه با سازنده‌های تولیدشده استفاده کنید:

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) نخواهد بود. علاوه بر این، اعمال تغییر با تأخیر همراه است و امکان بررسی خطا وجود ندارد.

رابط تولیدشده 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() استفاده کنید.

انواع اسکالر (رشته‌های نوع 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) توکار باشند، مفید باشد.

توابع 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 تغییر کنند، در حال حاضر هیچ تضمینی داده نمی‌شود.

نکته مهم این است که کدهای تولیدشده نباید در سیستم‌های کنترل نسخه ذخیره شوند و نباید در آرشیوهای توزیع کد مبدأ قرار گیرند.

لطفاً گزارش‌های خطا را به ردیاب خطاهای توزیع یا ردیاب خطاهای بالادستی در https://gitlab.gnome.org/GNOME/glib/issues/new ارسال فرمایید.

gdbus(1) <man:gdbus(1)>