PDFium bileşeni yerel kitaplığını işletim sistemi yükleyicisine bırakmak yerine sabit, sıralı bir arama zinciriyle bulur; çünkü açık olan bir dağıtım ağacı, ayıklayabileceğiniz bir dağıtım ağacıdır. Windows'ta o zincir, yükleyicinin zaten gönderdiği bir Win32 ya da Win64 alt dizinine bakar. Diğer hedeflerde alt dizin adını Free Pascal hedef makrolarından, <cpu>-<os> olarak kurar; böylece dağıtım ağacı, derlenmiş birim ağacıyla tam olarak aynı okunur. Son karar, bütün makaleye değer bir hata getirdi; çünkü neden bir büyük harf, belirti ise sessizlikti
Zincir, sırasıyla
Sırayla denenen dört konum, sonra en son çare olarak platform yükleyicisi. Birincisi tercih edilen düzen: çalıştırılabilir dosyanın yanında, hedef başına bir alt dizin içeren bir DLLs dizini. İkincisi, hedef alt dizininin doğrudan çalıştırılabilir dosyanın yanında olduğu alternatif düzen. Üçüncüsü düz eski düzen: kitaplık, hiç alt dizin olmadan çalıştırılabilir dosyanın yanında oturur. Dördüncüsü, yalnızca Windows'ta, sistem dizini; özen ister, çünkü 32 bitlik bir işlem SysWOW64 klasörüne, 64 bitlik işlem System32 klasörüne bakmalıdır ve 32 bitlik Windows'ta ilki yoktur, dolayısıyla aramanın geri düşmesi gerekir. Bütün bunlardan sonra yükleyicinin kendi başına araması istenir
Windows dışında bilinçli olarak sistem dizini adımı yoktur. Çalışma zamanı bağlayıcı yapılandırması ve kitaplık yolu ortamının yönettiği platform yükleyicisinin kendi arama yolu o zemini zaten kapsar ve onu Pascal'da çoğaltmak, dağıtıma göre değişen kuralları yeniden uygulamak demek olurdu. Windows zincirindeki başarısızlıkların teşhisi ayrı olarak PDFium DLL dağıtımı ve yükleme başarısızlıklarının teşhisinde kapsanır
Alt dizin adı nereden gelir
Windows'ta bu ad Win32 ya da Win64'tür; işletim sisteminin değil çalışan işlemin bitliğine göre karara bağlanır, çünkü hangi ikilinin yüklenebileceğini belirleyen odur. Diğer her yerde ad, derleyici hedef makrolarından kurulur; böylece iki mimari için derleme yapan bir makine net biçimde ayrılmış iki ağaç üretir ve yerel kitaplığı tutan klasör, derlenmiş birimleri tutan klasörün yanında aynı adla oturur
function BuildDllSubDir(UseV8: Boolean): string;
begin
{$IFDEF MSWINDOWS}
if IsWin64 then
Result := 'Win64'
else
Result := 'Win32';
{$ELSE}
// Derleyici makroları işletim sistemini büyük harfle başlatır ("Linux",
// "Darwin"); paket birim çıktı dizini başlatmaz, dolayısıyla ikisi
// yalnızca küçük harfe indirme sonrasında örtüşür. Büyük küçük harfe
// duyarlı bir dosya sisteminde o fark aramanın bütünüdür
Result := LowerCase({$I %FPCTARGETCPU%} + '-' + {$I %FPCTARGETOS%});
{$ENDIF}
end;
Bir büyük harf bütün zinciri nasıl bozdu
Derleyici makrosu hedef işletim sistemini baş harfi büyük yazarak yazar: Win64, Linux, Darwin. Lazarus paketi, birim çıktısını kendi hedef değişkeninden adlandırılmış bir dizine yazar; o da küçük harftir: win64, linux, darwin. Aynı şeyin iki yazımı ve Windows'ta, dosya sisteminin onları ayırt etmediği yerde fark etmenin hiçbir yolu yok
Linux'ta ikisi iki farklı dizindir. Paylaşılan nesneyi DLLs/x86_64-linux içine koyan bir dağıtım, DLLs/x86_64-Linux arayan bir yükleyiciye görünmez; dolayısıyla zincirin dört açık adımının tamamı ıskalar ve kod, platform yükleyicisinin aramasına bırakmaya düşer. Bazen çalışır, kitaplık tesadüfen sistem genelinde kuruluysa; bazen çalışmaz ve her iki durumda da özenle düzenlenmiş dağıtım ağacı hiçbir şey katmaz. Başarısızlığın hata mesajı yoktur, çünkü başarısız olan hiçbir şey yoktur: her adım, dosyanın baktığı yerde olmadığını doğru bildirdi
Yoklama programı: derlendi ve çalıştırıldı
Bu hata sınıfı okuyarak bulunamaz ve derleyerek de bulunamaz. Geliştirme makinesinde hiç derlenmeyen bir platform dalını doğrulamanın alışılmış tekniği, birimi geçici bir dizine kopyalamak, yeniden adlandırmak, platform koşullusunu hiç tanımlanmayan bir simgeyle değiştirmek ve kopyayı derlemektir; derlenirse o yoldaki uses bölümü ve çağrı imzaları en azından kendi içinde tutarlıdır. Bu, kendi kendine yeten bir birim için iyi çalışır
Burada çalışmaz. Ana bağlama birimi çok büyüktür ve LCL'yi çeker; dolayısıyla Windows sembolü kapatılmış olarak kopyalanıp derlenemez. Bunun yerine değişikliğin dokunduğu bir avuç işlev, küçük kendi kendine yeten bir programa kelimesi kelimesine aktarıldı ve o program çalıştırıldı. x86_64-Win64 yazdı ve uyuşmazlık bir satır çıktıda görünürdü. Aynı programı derlemek size hiçbir şey söylemezdi; çünkü dize tamamen geçerlidir, yanlış olan yalnızca değeridir
program ProbeSubDir;
{$MODE DELPHI}
uses
SysUtils;
begin
// Yazdırın, savunmayın. Mesele, bir makronun bu araç zincirinde
// gerçekte neye açıldığına bakmaktır
Writeln('raw: ', {$I %FPCTARGETCPU%}, '-', {$I %FPCTARGETOS%});
Writeln('folded: ', LowerCase({$I %FPCTARGETCPU%} + '-' +
{$I %FPCTARGETOS%}));
end.
Genel ders: platformlar arası bir değişikliğin konusu bir şeyin türü değil değeri olduğunda, yalnızca derlemeli doğrulama doğrulama değildir. Yazdırın. Delphi ile Free Pascal arasındaki platformlar arası derleyici farklarının daha geniş kümesi Delphi ve FPC çapraz derleyici tuzakları makalesinde toplanır
Platforma kendi yükleme başarısızlıklarını anlattırın
Yükleyicinin Windows dalı, bir yüklemenin başarısız olabileceği nedenleri elle sıralar; çünkü oradaki faydalı ayrımlar —bir mimari uyuşmazlığı, eksik bir geçişli bağımlılık, çözümlenmeyen bir yol— tek tek adlandırmaya değer hata kodlarına eşlenir. Windows dışında taşınabilir yükleyici birimi aynı zemini kapsayan betimleyici bir dizeyi zaten döndürür; dolayısıyla Windows dışı dal, farklı sistemlerde farklı anlamlara gelen bir hata numarasından kategorileri yeniden türetmek yerine onu doğrudan kullanır
O ikisini tek bir mesajda normalleştirme dürtüsüne direnmek bilinçlidir. Yükleme başarısızlığı bir dağıtım sorunudur ve mesajı okuyan kişinin onu aramak için platformun kendi sözcük dağarcığına ihtiyacı vardır
Özyinelemeye giren bir ad çakışması
Bir tuzak daha: küçük ve keskin. Taşınabilir yükleyici birimi, UnloadLibrary adında bir yordam dışa aktarır ve bağlama biriminde, tanıtıcıyı serbest bırakmadan önce kendi defter tutmasını yapan aynı adda bir yordam vardır. O yordamın içinde niteliksiz bir UnloadLibrary çağrısı, geçerli birimdekine çözülür; o da kendini çağırır. Düzeltme, çağrıyı birim adıyla nitelendirmektir
Bu, genel olarak Free Pascal portlarını domine eden tanımlayıcı gölgeleme sorunlarının biçiminin aynısıdır: Windows birimi, kayan noktalı olanları gölgeleyen tamsayı türünde asgari ve azami işlevlerini ve aynı addaki sınıfı gölgeleyen bir eşzamanlama türünü dışa aktarır ve her durumda çözüm, uses bölümünün sırasına bağlıdır. Çağrı noktasını nitelendirmek, birinin o sırayı daha sonra korumasına bağlı olmayan düzeltmedir
Dağıtım kontrol listesi
Yol aritmetiği doğru olduktan sonra yükleme başarısızlıklarının çoğunu üç şey açıklar. Mimari, makineyi değil işlemi eşlemelidir; dolayısıyla 64 bitlik Windows'taki 32 bitlik bir uygulamanın 32 bitlik ikiliye ihtiyacı vardır. V8 etkin derlemenin dosya adı farklıdır; dolayısıyla ikisini karıştıran bir dağıtım doğru görünür ve hiçbir şey yüklemez. Ve bir sistem dizininde aynı anda yalnızca bir varyant yaşayabilir; bu, sistem geneline bir şey kurmak yerine açık alt dizin düzenini tercih etmenin iyi bir nedenidir
Lazarus için özellikle şunu yapın: yerel kitaplığı küçük harfle DLLs/<cpu>-<os> altına, çalıştırılabilir dosyanın yanına koyun; her hedefte zincirin ilk adımı onu bulacaktır. Bunu Lazarus üzerinde deneyen görüntüleyici örneği Lazarus ve FPC görüntüleyici makalesinde betimlenir ve güncel platform desteği PDFium Delphi component ürün sayfasında listelenir