کتابخانه‌ی استاندارد · سیستم و ابزار

بارگذاری کتابخانه os.dl

بارگذاری کتابخانه‌ی اشتراکی هنگام اجرا، یافتن تابع‌هایش و فراخوانی اشاره‌گر تابع با تا هشت آرگومان صحیح یا اشاره‌گر.

واردسازی سیستم عامل.بارگذاری کتابخانه

نام آرگومان‌ها شناسه‌ی خود کد است و معادل فارسی ندارد؛ گونه‌ها، کلیدواژه‌ها و نام بسته‌ها با معادل فارسی نوشته می‌شوند.

بیشتر برنامه‌ها کتابخانه‌هایشان را موقع ساخت پیوند می‌دهند. این بسته برای حالت دیگر است: کتابخانه هنگام اجرای برنامه انتخاب می‌شود. باز کردن یک کتابخانه‌ی اشتراکی را بارگذاری می‌کند (dlopen)، نماد تابع یا متغیری را با نامش در آن می‌یابد (dlsym) و فراخوان اشاره‌گر تابعی را که گرفته‌اید با تا هشت آرگومان صحیح یا اشاره‌گر صدا می‌زند و عدد یا اشاره‌گر برگشتی را می‌دهد. باز کردن برنامه خود برنامه‌ی در حال اجرا را باز می‌کند، یعنی کتابخانه‌ی C و هر چیز دیگری که بارگذاری شده. پایه‌ی افزونه‌ها، سنجش کتابخانه‌های اختیاری و ابزارهایی است که تابعی را که تازه نوشته‌اند در حافظه‌ی اجرایی می‌گذارند.

آرگومان‌ها و نتیجه از نوع اندازه هستند، عددی به پهنای اشاره‌گر (روی سیستم ۶۴ بیتی ۶۴ بیت). اشاره‌گر را با تبدیل می‌دهید، (p برگردان تهی*) برگردان اندازه، و اشاره‌گر برگشتی را با r برگردان تهی* برمی‌گردانید. عدد کوچک همان‌طور که هست داده می‌شود. بسته روی لینوکس، مک و بی‌اس‌دی‌ها کار می‌کند؛ روی ویندوز پشتیبانی می شود نادرست است و تابع‌ها نتیجه‌ی خالی می‌دهند.

اشتباه‌های رایج:

  • صدا زدن چیزی که تابع نیست یا تابعی با شمار آرگومان نادرست. فراخوان نمی‌تواند این را بسنجد؛ اشاره‌گر نادرست یا شمار نادرست برنامه را از کار می‌اندازد یا آشغال برمی‌گرداند. دقیقاً همان آرگومان‌هایی را بدهید که تابع C می‌گیرد.
  • صدا زدن تابعی که ساختار به‌صورت مقدار یا فهرست آرگومان متغیر مثل printf می‌گیرد با فراخوان یا فراخوانی ترکیبی. این‌ها قرارداد فراخوانی دیگری دارند. آرگومان اعشاری فراخوانی ترکیبی می‌خواهد و نتیجه‌ی اعشاری فراخوانی ترکیبی اعشار.
  • نسنجیدن پوچ. وقتی کتابخانه یا نماد نیست باز کردن و نماد پوچ برمی‌گردانند و فراخوان روی پوچ ۰ می‌دهد؛ علتش را از خطا بپرسید.
  • استفاده از نماد بعد از بستن. وقتی آخرین کاربر کتابخانه را می‌بندد کدش می‌رود و اشاره‌گر کهنه برنامه را می‌اندازد.
  • بیش از ۸ آرگومان: فراخوان نمی‌پذیرد و ۰ برمی‌گرداند.

انتخاب تابع با نام در زمان اجرا

لازم نیست نام تابع هنگام نوشتن برنامه معلوم باشد. نمونه‌ی زیر با باز کردن برنامه خود برنامه‌ی در حال اجرا را باز می‌کند، هر نام را با نماد می‌یابد و آنچه را پیدا کرد صدا می‌زند. نامی که وجود ندارد پوچ می‌دهد و نمونه به‌جای صدا زدنش گزارشش می‌کند. برای کار با یک پرونده‌ی افزونه، مسیر آن را به باز کردن بدهید.

os-dl-guide-plugin.salam
// زبان: فارسی
واردسازی سیستم عامل.بارگذاری کتابخانه
واردسازی رشته

تابع صدا زدن با نام(کتابخانه: تهی*، نام: رشته، آرگومان: اندازه): رشته:
    نشانی := بارگذاری کتابخانه.نماد(کتابخانه، نام)
    اگر نشانی برابر پوچ:
        برگشت نام + ": not found"
    پایان
    برگشت نام + ": " + رشته.از عدد(بارگذاری کتابخانه.فراخوان(نشانی، [آرگومان]) برگردان صحیح۶۴)
پایان

تابع ریشه:
    اگر وارونه بارگذاری کتابخانه.پشتیبانی می شود():
        سرچاپ "dynamic loading is not available here"
        برگشت
    پایان
    کتابخانه := بارگذاری کتابخانه.باز کردن برنامه()
    اگر کتابخانه برابر پوچ:
        سرچاپ "cannot open the program:"، بارگذاری کتابخانه.خطا()
        برگشت
    پایان
    دیرکن _closed := بارگذاری کتابخانه.بستن(کتابخانه)
    متن := "salam"
    سرچاپ صدا زدن با نام(کتابخانه، "strlen"، (متن برگردان تهی*) برگردان اندازه)
    سرچاپ صدا زدن با نام(کتابخانه، "labs"، (0 - 42) برگردان اندازه)
    سرچاپ صدا زدن با نام(کتابخانه، "no_such_function"، 1 برگردان اندازه)
پایان
خروجیstrlen: 5 labs: 42 no_such_function: not found

باز کردن کتابخانه با مسیر

نام پرونده‌ی کتابخانه در سیستم‌های مختلف فرق دارد، پس برنامه‌ی قابل‌حمل چند نام را امتحان می‌کند و اولین نامی را که باز شد به کار می‌برد. باز کردن برای کتابخانه‌ای که نیست پوچ برمی‌گرداند و خطا دلیلش را می‌گوید. هر باز کردن موفق را با بستن جفت کنید و نمادی را بعد از بسته شدن کتابخانه‌اش به کار نبرید.

os-dl-guide-open.salam
// زبان: فارسی
واردسازی سیستم عامل.بارگذاری کتابخانه
واردسازی رشته

تابع اولین را باز کن(مسیرها: رشته[]): تهی*:
    هر مسیر در مسیرها:
        کتابخانه := بارگذاری کتابخانه.باز کردن(مسیر)
        اگر کتابخانه نابرابر پوچ:
            برگشت کتابخانه
        پایان
    پایان
    برگشت پوچ
پایان

تابع ریشه:
    اگر وارونه بارگذاری کتابخانه.پشتیبانی می شود():
        سرچاپ "dynamic loading is not available here"
        برگشت
    پایان
    کتابخانه := اولین را باز کن(["libno-such-library.so"، "libc.so.6"، "libc.dylib"، "/usr/lib/libSystem.B.dylib"، "libc.so.7"])
    اگر کتابخانه برابر پوچ:
        سرچاپ "no C library found:"، بارگذاری کتابخانه.خطا()
        برگشت
    پایان
    دیرکن _closed := بارگذاری کتابخانه.بستن(کتابخانه)
    سرچاپ "opened a C library"
    متن := "shared library"
    درازا := بارگذاری کتابخانه.فراخوان(بارگذاری کتابخانه.نماد(کتابخانه، "strlen")، [(متن برگردان تهی*) برگردان اندازه])
    سرچاپ "strlen says"، رشته.از عدد(درازا برگردان صحیح۶۴)
پایان
خروجیopened a C library strlen says 14

تابع‌ها

پشتیبانی می شود Supported

تابع پشتیبانی می شود(): منطقی
درست جایی که بارگذاری پویا کار می‌کند (هر سیستمی جز ویندوز).
os-dl-Call.salam
واردسازی سیستم عامل.بارگذاری کتابخانه

تابع ریشه:
    اگر وارونه بارگذاری کتابخانه.پشتیبانی می شود():
        سرچاپ "not supported here"
        برگشت
    پایان
    lib := بارگذاری کتابخانه.باز کردن برنامه()
    دیرکن بارگذاری کتابخانه.بستن(lib)
    text := "hello, world"
    length := بارگذاری کتابخانه.فراخوان(بارگذاری کتابخانه.نماد(lib، "strlen")، [(text برگردان تهی*) برگردان اندازه])
    سرچاپ "strlen:"، length
    سرچاپ "labs:"، بارگذاری کتابخانه.فراخوان(بارگذاری کتابخانه.نماد(lib، "labs")، [(0 - 42) برگردان اندازه])
    سرچاپ "missing symbol:"، بارگذاری کتابخانه.نماد(lib، "no_such_function") برابر پوچ
    missing := بارگذاری کتابخانه.باز کردن("libno-such-library.so.9")
    سرچاپ "missing library:"، missing برابر پوچ، بارگذاری کتابخانه.خطا().طول() بزرگتر 0
پایان
خروجیstrlen: 12 labs: 42 missing symbol: true missing library: true true

باز کردن Open

تابع باز کردن(path: رشته): تهی*
کتابخانه‌ی اشتراکی در path را بارگذاری می‌کند (نامی مثل libm.so.6 را خود سیستم جست‌وجو می‌کند) و دستگیره‌اش را برمی‌گرداند، یا پوچ.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-dl-Call.salam

باز کردن برنامه OpenSelf

تابع باز کردن برنامه(): تهی*
برنامه‌ی در حال اجرا را باز می‌کند تا نماد بتواند کتابخانه‌ی C و هر چیز بارگذاری‌شده را بیابد. جایی که پشتیبانی نمی‌شود پوچ.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-dl-Call.salam

نماد Sym

تابع نماد(lib: تهی*، name: رشته): تهی*
نشانی تابع یا متغیری به نام name در کتابخانه، یا پوچ. با سنجش پوچ، نه با استثنا.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-dl-Call.salam

بستن Close

تابع بستن(lib: تهی*): منطقی
کتابخانه را پس می‌دهد؛ در موفقیت درست. بعدش از نمادهایش استفاده نکنید.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-dl-Call.salam

خطا Error

تابع خطا(): رشته
متن سیستم برای آخرین شکست باز کردن یا نماد، یا رشته‌ی خالی.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-dl-Call.salam

فراخوان Call

تابع فراخوان(fn: تهی*، args: size): size
تابع در fn را با آرگومان‌های صحیح و اشاره‌گر args (۰ تا ۸ تا) صدا می‌زند و نتیجه‌ی صحیح یا اشاره‌گرش را برمی‌گرداند. اشاره‌گر پوچ یا بیش از ۸ آرگومان ۰ می‌دهد. آرگومان‌ها در همان ثبات‌ها و جای‌های پشته‌ای داده می‌شوند که کامپایلر C می‌داد.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-dl-Call.salam

فراخوانی ترکیبی CallMixed

تابع فراخوانی ترکیبی(fn: تهی*، ints: size، dbls: اعشار۶۴): size
مثل فراخوان برای تابعی که آرگومان صحیح یا اشاره‌گر (تا ۶ تا در ints) و آرگومان اعشاری (تا ۸ تا در dbls) می‌گیرد و صحیح یا اشاره‌گر برمی‌گرداند. روی x86-64 (System V) و ARM ۶۴ بیتی این دو دسته در ثبات‌های جدا می‌روند، پس ترتیب آمیختن‌شان در نمونه‌ی C مهم نیست: ldexp(double, int) یعنی ints = [exp] و dbls = [x]. برای فهرست آرگومان متغیر نیست. اشاره‌گر پوچ یا آرگومان بیش از حد ۰ می‌دهد.
os-dl-CallMixed.salam
واردسازی سیستم عامل.بارگذاری کتابخانه

تابع ریشه:
    اگر وارونه بارگذاری کتابخانه.پشتیبانی می شود():
        سرچاپ "not supported here"
        برگشت
    پایان
    lib := بارگذاری کتابخانه.باز کردن برنامه()
    دیرکن بارگذاری کتابخانه.بستن(lib)
    ناپایا m := lib
    اگر سلام سیستم لینوکس:
        m = بارگذاری کتابخانه.باز کردن("libm.so.6")
    پایان
    سرچاپ "pow:"، بارگذاری کتابخانه.فراخوانی ترکیبی اعشار(بارگذاری کتابخانه.نماد(m، "pow")، [0 برگردان اندازه]، [2.0، 10.0])
    سرچاپ "ldexp:"، بارگذاری کتابخانه.فراخوانی ترکیبی اعشار(بارگذاری کتابخانه.نماد(m، "ldexp")، [3 برگردان اندازه]، [1.5])
    سرچاپ "lround:"، بارگذاری کتابخانه.فراخوانی ترکیبی(بارگذاری کتابخانه.نماد(m، "lround")، [0 برگردان اندازه]، [2.6])
پایان
خروجیpow: 1024 ldexp: 12 lround: 3

فراخوانی ترکیبی اعشار CallMixedF64

تابع فراخوانی ترکیبی اعشار(fn: تهی*، ints: size، dbls: اعشار۶۴): اعشار۶۴
همان فراخوانی برای تابعی که double برمی‌گرداند، مثل pow یا hypot.

نمونه‌ی این مورد همراه با موارد بالاتر آمده است: os-dl-CallMixed.salam