Bağladığınız soru, İkili Kitaplıklarıyla Bağlantılandır "işlevselliğine, katıştırılmış bir ikili dosyadan biraz farklıdır.
"İkili Kitaplıklarıyla Bağla", bağlantıyla ilgili olarak beklediğiniz şey anlamına gelir: İkili dosya, statik kitaplık mı, dinamik kitaplık mı yoksa çerçeve mi olursa olsun, derleme işleminden sonraki bağlantı zamanında nesne kodunuza bağlanır.
Statik bir kitaplıkla bağlantıyı düşündüğünüzde, ne olduğu oldukça açıktır: bağlayıcı , kodu kitaplıktan (örn. ) Çıktı ikili dosyaya kopyalarlibFoo.a
. Çıktı dosyanızın boyutu büyür, ancak çalışma zamanında harici bağımlılıkları çözmeniz gerekmez. Programınızın çalışması için gereken her şey (statik kitaplıkla ilgili olarak) oluşturulduktan sonra hazır olur.
Dinamik bir kitaplıkla (.dylib veya sistem tarafından sağlanan çerçeve), beklediğiniz kitaplığın, programınızı çalıştırdığınızda sistemin dinamik kitaplık yükleyici yolunda bir yerde bulunmasıdır. Bu şekilde, tüm üçüncü taraf harici kütüphaneleri ikili dosyaya kopyalama yükünüz olmaz ve bu kütüphaneye bağlanan bir bilgisayardaki tüm farklı programlar onu bulabilir, bu da en az disk alanı kazandırır, aynı zamanda sistemin kütüphaneleri nasıl ve nerede önbelleğe aldığına bağlı olarak potansiyel olarak bellek alanı.
Bir çerçeve, dinamik bir kitaplığa çok benzer, ancak dizin yapısında (resimler, ses, diğer çerçeveler vb.) Kaynaklar içerebilir. Eğer sadece bu yüzden bir çerçeveye bağlantıya sahip olabilir, böylece bu durumda basit bir statik kitaplık veya .dylib dosya kesmeyecek o düzgün çalışmasına gerekenleri bulabilirsiniz.
Üçüncü taraf bir çerçeveye bağladığınızda (github'dan indirip kendiniz oluşturduğunuz bir şey söyleyin), üzerinde çalışmayı düşündüğünüz sistemde bulunmayabilir. Bu durumda, yalnızca çerçeveye bağlanmakla kalmaz, aynı zamanda "Çerçeveleri Kopyala" aşamasını kullanarak da uygulama paketinizin içine yerleştirirsiniz. Programınız çalıştığında, çalışma zamanı-bağlayıcısı (çözümleyici olarak da bilinir) sistem yükleyici yoluna ek olarak paketinizin içine bakar, katıştırılmış çerçeveyi bulur ve uygulamanızın çalışması için gereken koda sahip olmasını sağlar.
Son olarak, düzgün bir şekilde "gömülü ikili" olan şey, her ikisi de uygulama paketinize bir Kopya Dosyaları Aşaması aracılığıyla katıştırdığınız ve belki de bir çağrı popen()
veya benzeri bir yöntemle yürüttüğünüz bir yürütülebilir dosyadır . Gömülü ikili programınız tarafından çağrılabilir, ancak programla bağlantılı değildir. Tamamen harici bir varlıktır ( /bin
dizindeki programlar gibi ).
Uygulamada, sistem tarafından sağlanan kütüphaneler ve çerçeveler için bunlara bağlanacaksınız ve tek yapmanız gereken bu.
Oluşturduğunuz, gömülü kaynak gerektirmeyen (yani bir çerçeve olmasını gerektirmeyen) bir kitaplığı bağlamanız gerekiyorsa, statik bir kitaplığa bağlanabilirsiniz. Programınızda aynı kütüphane kodunu kullanmak isteyen birden fazla modül olduğunu fark ederseniz, onu bir çerçeveye veya dinamik kütüphaneye dönüştürmek ve bunlara bağlantı kurmak yerden tasarruf sağlayabilir ve kullanışlı olabilir (özellikle bellek kullanımı endişe kaynağıysa).
Son olarak, çerçeveler yalnızca kaynakları değil, başlık ve / veya lisans dosyalarını da içerebilir. Bu dosyaları iletmek için bir çerçeve kullanmak aslında uygun bir dağıtım mekanizmasıdır, bu nedenle çoğu zaman bir çerçeveyi dahil etmek isteyebilirsiniz, böylece bu şeyler ikili dosyanızla birlikte etiketleyebilir (yani lisans gereksinimleri bunu zorunlu kılabilir).
--- DÜZENLE ---
Adam Johns aşağıdaki soruyu yorum olarak gönderdi:
Bu harika bir cevap. Yine de biraz kafam karıştı. İkili dosyayı kendiniz yürütmek ne demektir? Sadece gömülü çerçevenin kodunu kullanmak mı istiyorsunuz? Popen () 'dan bahsettiğinizi biliyorum, ancak uygulamamın popen () çağırdığını söylüyorsunuz? Bunun ne anlama geldiğini gerçekten bilmiyorum.
Katıştırılmış bir ikili , dosya yerine yürütülebilir bir komut satırı aracı olmasına rağmen, paketinizdeki ses dosyası veya görüntü gibi başka bir kaynak dosyası olduğunu söylüyorum . popen()
Fonksiyonu ( man popen
Başka eden programın rasgele programları yürütmek sağlar yaklaşık terminal den fazla okumak için). system()
Fonksiyon başka bir yoludur. Başkaları da var ve burada gömülü bir ikiliyi daha anlaşılır hale getirebilecek tarihsel bir örnek vereceğim:
Muhtemelen bildiğiniz gibi, Mac OS X'te bir uygulama başlattığınızda mevcut kullanıcının kullanıcı kimliğiyle başlatılır. En yaygın yüklemelerde, admin
kullanıcı kimliği verilen varsayılan Masaüstündeki kullanıcıdır 501
.
Unix tabanlı işletim sistemlerinde yalnızca root
kullanıcı (kullanıcı kimliği 0
) tüm dosya sistemine tam erişime sahiptir. Bazen Masaüstü kullanıcısı tarafından başlatılan bir yükleyici programının dosyaları ayrıcalıklı bir dizine (örneğin sürücüler) yüklemesi gerekebilir. Bu durumda, uygulama programının bu ayrıcalıklı root
dizinlere yazabilmesi için kullanıcıya ayrıcalıklarını artırması gerekir .
OS X 10.7 aracılığıyla işletim sistemlerinde bunu kolaylaştırmak için Apple, Yetkilendirme Hizmetleri API'sında AuthorizationExecuteWithPrivileges () işlevini sağlamıştır (bu artık kullanımdan kaldırılmıştır, ancak yine de yararlı bir örnektir).
AuthorizationExecuteWithPrivileges()
argüman olarak yürütmek için bir komut satırı aracının yolunu aldı root
. Komut satırı aracı, yükleme mantığınızı çalıştırmak için yazdığınız yürütülebilir bir kabuk komut dosyası veya derlenmiş bir ikili dosyadır. Bu araç, diğer tüm kaynak dosyaları gibi uygulama paketinizin içine yüklenmiştir.
İşletim sistemi çağrıldığında, kullanıcı şifresini isteyen bir yetkilendirme iletişim kutusu açar (bunu daha önce görmüştünüz!) Ve girildiğinde programı root
uygulamanızın adına uygular. Bu işlem sadece popen()
kendinizle bir program yürütmeye benzer , ancak popen()
tek başına size ayrıcalık yükseltme avantajı sağlamaz.