Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Dinamik bağlantı kitaplığına (DLL) isteğe bağlı bir giriş noktası. Sistem bir işlemi veya iş parçacığını başlattığında veya sonlandırdığında, işlemin ilk iş parçacığını kullanarak yüklenen her DLL için giriş noktası işlevini çağırır. Sistem, LoadLibrary ve FreeLibrary işlevleri kullanılarak yüklendiğinde veya kaldırıldığında DLL için giriş noktası işlevini de çağırır.
Warning
DLL giriş noktasında güvenle yapabileceklerinizde önemli sınırlar vardır. Bkz. DllMain'de aranması güvenli olmayan belirli Windows API'leri için Genel En İyi Yöntemler. En basit başlatma dışında herhangi bir şeye ihtiyacınız varsa bunu DLL için bir başlatma işlevinde yapın. DllMain çalıştırıldıktan sonra ve DLL'deki diğer işlevleri çağırmadan önce uygulamaların başlatma işlevini çağırmasını gerektirebilirsiniz.
Örnek
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpvReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
if (lpvReserved != nullptr)
{
break; // do not do cleanup if process termination scenario
}
// Perform any necessary cleanup.
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
Bu, Dynamic-Link Kitaplığı Entry-Point İşlevinden bir örnektir.
Syntax
BOOL WINAPI DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_ LPVOID lpvReserved
);
Parameters
-
hinstDLL [in]
-
DLL modülünün tanıtıcısı. Değer, DLL'nin temel adresidir. BIR DLL'nin HINSTANCE'ı DLL'nin HMODULE'si ile aynıdır, bu nedenle hinstDLL modül tanıtıcısı gerektiren işlevlere yapılan çağrılarda kullanılabilir.
-
fdwReason [in]
-
DLL giriş noktası işlevinin neden çağrıldığını gösteren neden kodu. Bu parametre aşağıdaki değerlerden biri olabilir.
Değer Anlamı - DLL_PROCESS_ATTACH
- 1
DLL, işlemin başlatılmasının veya LoadLibrary çağrısının sonucu olarak geçerli işlemin sanal adres alanına yükleniyor. DLL'ler bu fırsatı kullanarak örnek verilerini başlatabilir veya tlsAlloc işlevini kullanarak bir iş parçacığı yerel depolama (TLS) dizini ayırabilir.
lpvReserved parametresi DLL'nin statik olarak mı yoksa dinamik olarak mı yüklendiğini gösterir.- DLL_PROCESS_DETACH
- 0
Dll, başarısız bir şekilde yüklendiğinden veya başvuru sayısı sıfıra ulaştığından çağırma işleminin sanal adres alanından kaldırılıyor (işlemler LoadLibrary olarak adlandırıldığı her zaman için bir kez sonlandırıldı veya FreeLibrary olarak adlandırıldı).
lpvReserved parametresi, Bir FreeLibrary çağrısı, yükleme hatası veya işleme sonlandırması nedeniyle DLL'nin kaldırılıp kaldırılmadığını gösterir.
DLL, TlsAlloc kullanılarak ayrılan tüm TLS dizinlerini serbest bırakabilmek ve iş parçacığı yerel verilerini serbest bırakabilmek için TlsFree işlevini çağırmak için bu fırsatı kullanabilir.
DLL_PROCESS_DETACH bildirimini alan iş parçacığının, DLL_PROCESS_ATTACH bildirimini alan iş parçacığının aynı olması gerekmediğini unutmayın.- DLL_THREAD_ATTACH
- 2
Geçerli işlem yeni bir iş parçacığı oluşturuyor. Bu durumda sistem, şu anda işleme bağlı olan tüm DLL'lerin giriş noktası işlevini çağırır. Çağrı yeni iş parçacığı bağlamında yapılır. DLL'ler iş parçacığı için bir TLS yuvası başlatmak için bu fırsatı kullanabilir. DLL_PROCESS_ATTACH ile DLL giriş noktası işlevini çağıran bir iş parçacığı, DLL_THREAD_ATTACH ile DLL giriş noktası işlevini çağırmaz.
Dll'nin giriş noktası işlevinin bu değerle çağrıldığını, yalnızca DLL işlem tarafından yüklendikten sonra oluşturulan iş parçacıkları tarafından çağrıldığını unutmayın. LoadLibrary kullanılarak bir DLL yüklendiğinde, mevcut iş parçacıkları yeni yüklenen DLL'nin giriş noktası işlevini çağırmaz.- DLL_THREAD_DETACH
- 3
Bir iş parçacığı temiz bir şekilde çıkılıyor. DLL, ayrılmış belleği TLS yuvasında depolamak için bir işaretçi depoladıysa, belleği boşaltmak için bu fırsatı kullanmalıdır. Sistem, şu anda yüklü olan tüm DLL'lerin giriş noktası işlevini bu değerle çağırır. Çağrı, çıkan iş parçacığı bağlamında yapılır. -
lpvReserved [in]
-
fdwReasonDLL_PROCESS_ATTACH ise, dinamik yükler için lpvReservedNULL, statik yükler için null değildir.
fdwReasonDLL_PROCESS_DETACH ise, FreeLibrary çağrıldığında lpvReservedNULL olur veya işlem sonlandırılıyorsa DLL yükü başarısız olur ve NULL değildir.
Dönüş değeri
Sistem dllmain işlevini DLL_PROCESS_ATTACH değeriyle çağırdığında, işlev başarılı olursa TRUE veya başlatma başarısız olursa YANLIŞ döndürür. İşlem LoadLibrary işlevini kullandığından DllMain çağrıldığında dönüş değeri YANLIŞ ise, LoadLibrary NULL döndürür. (Sistem, DLL_PROCESS_DETACH ile giriş noktası işlevinizi hemen çağırır ve DLL'yi kaldırır.) İşlem başlatma sırasında DllMain çağrıldığında dönüş değeri YANLIŞ ise, işlem bir hatayla sonlandırılır. Genişletilmiş hata bilgilerini almak için GetLastError'ı arayın.
Sistem DllMain işlevini DLL_PROCESS_ATTACH dışında bir değerle çağırdığında, dönüş değeri yoksayılır.
Remarks
DllMain , kitaplık tanımlı işlev adı için bir yer tutucudur. DLL'nizi oluştururken kullandığınız gerçek adı belirtmeniz gerekir. Daha fazla bilgi için geliştirme araçlarınızla birlikte verilen belgelere bakın.
İlk işlem başlatma sırasında veya LoadLibrary çağrısından sonra sistem, işlem için yüklenen DLL'lerin listesini tarar. sistem, DLL_PROCESS_ATTACH değeriyle çağrılmamış her DLL için DLL'nin giriş noktası işlevini çağırır. Bu çağrı, işlemin birincil iş parçacığı veya LoadLibrary olarak adlandırılan iş parçacığı gibi işlem adres alanının değişmesine neden olan iş parçacığı bağlamında yapılır. Giriş noktasına erişim, sistem tarafından işlem genelinde seri hale getirilir. DllMain'deki iş parçacıkları, ek DLL'lerin dinamik olarak yüklenebilmesi veya başlatılmaması için yükleyici kilidini tutar.
DLL'nin giriş noktası işlevi bir DLL_PROCESS_ATTACH bildiriminden sonra FALSE döndürürse, bir DLL_PROCESS_DETACH bildirimi alır ve DLL hemen kaldırılır. Ancak , DLL_PROCESS_ATTACH kodu bir özel durum oluşturursa, giriş noktası işlevi DLL_PROCESS_DETACH bildirimini almaz.
Giriş noktası işlevi hiçbir zaman iş parçacığı için DLL_THREAD_ATTACH ile çağrılmasa bile sonlandırıcı iş parçacığı için giriş noktası işlevinin çağrıldığı durumlar vardır:
- İş parçacığı işlemdeki ilk iş parçacığı olduğundan sistem , DLL_PROCESS_ATTACH değeriyle giriş noktası işlevini çağırdı.
- LoadLibrary işlevine bir çağrı yapıldığında iş parçacığı zaten çalışıyordu, bu nedenle sistem hiçbir zaman onun için giriş noktası işlevini çağırmadı.
DLL'nin başarısız bir yükü, işlemin sonlandırılması veya FreeLibrary çağrısı sonucu bir DLL bir işlemden kaldırıldığında, sistem dll'nin giriş noktası işlevini işlemin tek tek iş parçacıkları için DLL_THREAD_DETACH değeriyle çağırmaz. DLL'ye yalnızca DLL_PROCESS_DETACH bildirimi gönderilir. DLL'ler, DLL tarafından bilinen tüm iş parçacıklarının tüm kaynaklarını temizlemek için bu fırsatı değerlendirebilir.
DLL_PROCESS_DETACH işlenirken, DLL'nin yığın belleği gibi kaynakları boşaltması için DLL'nin dinamik olarak kaldırılması gerekir (lpvReserved parametresi NULL'dir). İşlem sonlandırılıyorsa ( lpvReserved parametresi NULL değil), geçerli iş parçacığı dışındaki işlemdeki tüm iş parçacıkları zaten çıktı veya ExitProcess işlevine yapılan bir çağrıyla açıkça sonlandırıldı ve bu da yığınlar gibi bazı işlem kaynaklarını tutarsız bir durumda bırakabilir. Bu durumda, DLL'nin kaynakları temizlemesi güvenli değildir. Bunun yerine, DLL işletim sisteminin belleği geri almasına izin vermelidir.
TerminateProcess veya TerminateJobObject çağırarak bir işlemi sonlandırırsanız, bu işlemin DLL'leri DLL_PROCESS_DETACH bildirim almaz. TerminateThread çağrısı yaparak bir iş parçacığını sonlandırırsanız, bu iş parçacığının DLL'leri DLL_THREAD_DETACH bildirim almaz.
Giriş noktası işlevi yalnızca basit başlatma veya sonlandırma görevlerini gerçekleştirmelidir. LoadLibrary veya LoadLibraryEx işlevini (veya bu işlevleri çağıran bir işlevi) çağırmamalıdır, çünkü bu durum DLL yükleme düzeninde bağımlılık döngüleri oluşturabilir. Bu, sistem başlatma kodunu yürütmeden önce bir DLL'nin kullanılmasına neden olabilir. Benzer şekilde, giriş noktası işlevi işlem sonlandırma sırasında FreeLibrary işlevini (veya FreeLibrary'yi çağıran bir işlevi) çağırmamalıdır, çünkü bu durum sistem sonlandırma kodunu yürütdükten sonra bir DLL'nin kullanılmasına neden olabilir.
giriş noktası işlevi çağrıldığında Kernel32.dll işlem adres alanına yüklenmesi garanti edildiğinden, Kernel32.dll'deki işlevlerin çağrılması başlatma kodu yürütülmeden önce DLL'nin kullanılmasına neden olmaz. Bu nedenle, giriş noktası işlevi Kernel32.dll diğer DLL'leri yüklemeyen işlevleri çağırabilir. Örneğin , DllMain kritik bölümler ve mutex'ler gibi eşitleme nesneleri oluşturabilir ve TLS kullanabilir. Ne yazık ki, Kernel32.dlliçinde güvenli işlevlerin kapsamlı bir listesi yoktur.
Kernel32.dll dışındaki DLL'ler gerektiren işlevleri çağırmak, tanılaması zor sorunlara neden olabilir. Örneğin, bazı işlevler diğer sistem bileşenlerini yüklediğinden User, Shell ve COM işlevlerini çağırmak erişim ihlali hatalarına neden olabilir. Buna karşılık, sonlandırma sırasında bunlar gibi işlevleri çağırmak, ilgili bileşen zaten kaldırılmış veya başlatılmamış olabileceğinden erişim ihlali hatalara neden olabilir.
DLL bildirimleri seri hale getirildiğinden, giriş noktası işlevleri diğer iş parçacıkları veya işlemlerle iletişim kurmaya çalışmamalıdır. Sonuç olarak kilitlenmeler oluşabilir.
DLL yazarken en iyi yöntemler hakkında bilgi için bkz . Dinamik bağlantı kitaplığı en iyi yöntemleri.
DLL'niz C çalışma zamanı kitaplığı (CRT) ile bağlantılıysa, CRT tarafından sağlanan giriş noktası genel ve statik C++ nesneleri için oluşturucuları ve yıkıcıları çağırır. Bu nedenle , DllMain için bu kısıtlamalar oluşturucular ve yıkıcılar ve onlardan çağrılan tüm kodlar için de geçerlidir.
DLL'niz statik C çalışma zamanı kitaplığı (CRT) ile bağlantılı olmadığı sürece, DLL_PROCESS_ATTACH alırken DisableThreadLibraryCalls çağrısı yapmayı göz önünde bulundurun.
Requirements
| Requirement | Değer |
|---|---|
| Desteklenen en düşük düzeydeki istemci |
Windows XP [yalnızca masaüstü uygulamaları] |
| Desteklenen en düşük sunucu |
Windows Server 2003 [yalnızca masaüstü uygulamaları] |
| Header |
|