شاید با مفهوم کلی کتابخانه ها در برنامه نویسی آشنا باشید اما در این مقاله مختصر توضیحی در مورد کتابخانهها و رابطه آنها در لینوکس خواهیم پرداخت .
کتابخانه که بسته های قابل اشتراک گذاری (shared component) است، به مجوعهای از کلاسها و اشیاء (Object and Class) برنامهنویسی گفته میشود که با الحاق و کامپایل، کتابخانهای از توابع را ایجاد میکنند.این قابلیت مفهومی به نام برنامه نویسی ماژولار ( Modular Programing) را ایجاد کرده است.
معمولا توابع و کلاس های زبان C و یا دیگر زبان ها، که میتوانند در برنامههای مختلفی استفاده شوند تشکیل یک کتابخانه داده تا بتوان از یک فایل که شامل توابع مختلفی است برای برنامه های دیگر استفاده کرد و نیازی به استفاده از کلاس ها و توابع در هر برنامه به صورت مجزا نباشد، به عنوان مثال برنامههای مختلف در یک سیستم می توانند از یک کتابخانه GUI به منظور ایجاد نوار ابزار و … استفاده کنند.
به طور کلی کتابخانه ها به دو دسته تقسیم می شوند:
کتابخانههای پویا یا (Shared libraries (Dynamic libraries و یا کتابخانه های ثابت .Static libraries
گاهی برخی از این بستهها و به عبارتی کتابخانهها تا حدی بزرگ میشوند که بارگذاری آن برای یک برنامه حجم زیادی از فضای رم و هارد سیستم را اشغال می کنند و گاهی شاید فقط یک قسمتی از برنامه هر از چند گاهی نیاز به استفاده از این کتابخانه را داشته باشد. در این هنگام مفهوم کتابخانه های پویا (dynamic libraries) و کتابخانه های ثابت (static libraries) به میان میآید.
کتاب خانه های ثابت (Static Libraries) :
با توجه به توضیحات بالا وجود اینگونه کتابخانهها در زمان کامپایل یک برنامه ضروری است. یکی از مشکلاتی که این نوع کتابخانه ها دارند این است که آنها به صورت ثابت برای اجرای هر برنامه نیاز به کامپایل دارند. به عبارتی هر برنامه به صورت مستقل نیاز به اجرا و بارگیری این بسته در حافظه سیستم دارد که منجر به مصرف زیاد حافظه و منابع سیستم نظیر دیسک می شود .
در واقع کتابخانههای ایستا زمانی مناسب هستند که یک برنامه کوچک باشد و نیاز به توابع کمی داشته باشد. اما برای برنامه های بزرگ لازم است که از کتابخانه های پویا استفاده کرد که در ادامه به آنها خواهیم پرداخت.
همچنین از دیگر معایب کار با کتابخانههای ایستا این است که در صورت بهبود این نوع کتابخانه ها به عنوان مثال اضافه شدن یک تابع و قابلیتی جدید در آن، برای استفاده از نسخه جدید لازم است که برنامه شما مجدد با آن نسخه کامپایل شود و همچنین این نوع کتابخانهها به صورت ثابت فضای حافظه را اشغال میکنند.
کتابخانه های پویا (Dynamic Libraries ) :
برای برنامههایی که از تعداد زیادی کتابخانه استفاده میکنند، لازم است که از کتابخانههای به اشتراک گذاشته شده ( Shared libraries ) استفاده کرد. همان طور که از اسم این نوع کتابخانهها مشخص است، قابلیت اشتراکگذاری توابع را برای برنامههای مختلف در زمان اجرای برنامه و یا هنگامی که نیاز دارند فراهم می کنند.
در واقع این نوع کتابخانه تنها یک بار در فضای حافظه بارگذاری می شود و دیگر برنامهها امکان استفاده از کدها و توابع بارگذاری شده در برنامه خود را دارند.
در دنیای لینوکس این دو کتابخانه را ما با فرمت .so به معنای Shared Objectو یا با فرمت .a به معنای Static Object می باشند؛ می شناسیم.
کتابخانه های پویا را می توان به دو طریق استفاده کرد :
– به صورت پویا در زمان اجرای برنامه لینک شده اند (Dynamic linking)، در این حالت لینوکس میتواند کتابخانه را در زمان اجرای برنامه بارگیری کند، البته در صورتی که کتابخانه توسط برنامه دیگری بارگیری شده باشد این عمل مجددا انجام نمیشود.
– به صورت کاملا پویا که میتواند load و unload شوند و هنگامی که یک برنامه نیاز به فراخوانی یک تابع داشته باشد، آن کتابخانه بارگیری و فراخوانی میشود.این روشی رایج برای ایجاد برنامههایی است که قابلیت پشتیبانی از افزونهها را دارند، مانند مرورگر ها!
زمانی که یک برنامه اجرا میشود کتابخانههای مرتبط با آن در صورتی که از قبل بارگیری نشده باشند توسط مفسر(interpreter) بارگیری میشوند.
به عنوان مثال ما برنامه باینری ls که به منظور لیست کردن فایل استفاده میشود را مورد بررسی قرار میدهیم.
root@server lib64]# file /bin/ls]
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.18, strippe
همانطور که مشاهده میکنید این فایل یک فایل باینری و قابل اجرا است که توسط ELF یا Executable Linking Format مدیریت میشود و به صورت پویا لینک شده است.
Interpreter ELF وظیفه اجرای کتابخانههای یک برنامه را دارد؛ هر فایل اجرایی شامل یکheader است که مشخصات کتابخانهها و کدهای استفادهشده و نقطه شروع (start point) را مشخص می کند.
مفسر مربوط به فراخوانی کتابخانهها که در تصویر زیر مشاهده میشود ، ld-linux-x86-64.so.2 است که به فایل ld-2.12.so لینک شده است.
این فایل که خود به صورت کتابخانهای از توابع و کلاسها است به صورت ایستا لینک شده است، زمانی که یک کتابخانه پویا به صورت لینک شده نیاز است، هسته لینوکس این لینک را اجرا و مقداردهی میکند تا بتواند کتابخانههای مرتبط با یک برنامه را لود کند.
root@server lib64]# ldd /lib64/ld-2.12.so]
statically linked
زمانی که کار اجرای بارگیری کتابخانهها انجام شد، جابجایی صورت گرفته در مرحله قبل به حالت اولیه بازگشته و کنترل برای اجرا به برنامه داده میشود و هنگام خروج از یک برنامه این وظیفه لینکر است تا سیگنالهای مربوط به توقف اجرای یک کتابخانه را به CPU ارسال کند.
علیرغم این روند که به صورت کاملا خودکار و توسط یک هدایتگر ( لینکر ) انجام میشود، میتوان مدیریت اجرای یک کتابخانه را به برنامه داد. از این رو برنامه میتواند مشخص کند کدام کتابخانه نیاز به بارگیری دارد. در این مرحله برنامه کتابخانه را به عنوان یک فایل اجرایی اجرا میکند تا بتواند از توابع داخل آن استفاده کند؛ در این مرحله ازAPI هایی که مرتبط با بارگیری و بارگذاری یک کتابخانه هستند استفاده خواهد شد.
از API های مهم میتوان به موارد زیر اشاره کرد.
dlopen Makes an object file accessible to a program
dlsym Obtains the address of a symbol within a dlopened object file
dlerror Returns a string error of the last error that occurred
dlclose Closes an object file
بن مایه: https://blog.iranserver.com