Diğer cevapların bazılarının önerilerinin aksine, DllImport
niteliği kullanmak hala doğru yaklaşımdır.
Dürüst olmak gerekirse neden dünyadaki herkes gibi yapamıyorsunuz ve DLL için göreceli bir yol belirtmiyorum . Evet, uygulamanızın yükleneceği yol farklı kişilerin bilgisayarlarında farklılık gösterir, ancak bu dağıtım konusunda temelde evrensel bir kuraldır. DllImport
Mekanizma Bu düşünceyle tasarlanmıştır.
Aslında, bunu bile DllImport
halledemez. Kullanışlı yönetilen sarmalayıcıları (P / Invoke marshaller sadece çağırır LoadLibrary
) kullanıp kullanmadığınızdan bağımsız olarak işleri yöneten yerel Win32 DLL yükleme kurallarıdır . Bu kurallar burada ayrıntılı olarak numaralandırılmıştır , ancak önemli kurallar burada belirtilmiştir:
Sistem bir DLL dosyasını aramadan önce aşağıdakileri kontrol eder:
- Aynı modül adına sahip bir DLL zaten belleğe yüklenmişse, sistem hangi dizinde olursa olsun yüklü DLL'yi kullanır. Sistem DLL'yi aramaz.
- DLL, uygulamanın çalıştığı Windows sürümü için bilinen DLL listesindeyse, sistem bilinen DLL (ve varsa bilinen DLL bağımlı DLL) kopyasını kullanır. Sistem DLL'yi aramaz.
Eğer SafeDllSearchMode
(varsayılan) etkinleştirildiğinde aşağıdaki gibi arama sırası:
- Uygulamanın yüklendiği dizin.
- Sistem dizini.
GetSystemDirectory
Bu dizinin yolunu almak için işlevi kullanın .
- 16 bit sistem dizini. Bu dizinin yolunu alan bir işlev yoktur, ancak aranır.
- Windows dizini.
GetWindowsDirectory
Bu dizinin yolunu almak için işlevi kullanın .
- Geçerli dizin.
PATH
Ortam değişkeninde listelenen dizinler . Bunun, Uygulama Yolları kayıt defteri anahtarı tarafından belirtilen uygulama başına yolu içermediğini unutmayın. Uygulama yolları anahtarı, DLL arama yolu hesaplanırken kullanılmaz.
Bu nedenle, DLL'nizi bir sistem DLL'si ile aynı şekilde adlandırmıyorsanız (ki hiçbir koşulda hiçbir zaman yapmamanız gerekir), varsayılan arama sırası uygulamanızın yüklendiği dizinde aramaya başlayacaktır. DLL dosyasını yükleme sırasında oraya yerleştirirseniz bulunur. Göreli yolları kullanırsanız, tüm karmaşık sorunlar ortadan kalkar.
Sadece yaz:
[DllImport("MyAppDll.dll")] // relative path; just give the DLL's name
static extern bool MyGreatFunction(int myFirstParam, int mySecondParam);
Ancak bu herhangi bir nedenle işe yaramazsa ve uygulamayı DLL için farklı bir dizine bakmaya zorlamanız gerekiyorsa, SetDllDirectory
işlevi kullanarak varsayılan arama yolunu değiştirebilirsiniz .
Belgelere göre:
Aramadan sonra SetDllDirectory
standart DLL arama yolu:
- Uygulamanın yüklendiği dizin.
lpPathName
Parametre tarafından belirtilen dizin .
- Sistem dizini.
GetSystemDirectory
Bu dizinin yolunu almak için işlevi kullanın .
- 16 bit sistem dizini. Bu dizinin yolunu alan bir işlev yoktur, ancak aranır.
- Windows dizini.
GetWindowsDirectory
Bu dizinin yolunu almak için işlevi kullanın .
PATH
Ortam değişkeninde listelenen dizinler .
DLL'den ilk kez içe aktarılan işlevi aramadan önce bu işlevi çağırdığınız sürece, DLL'leri bulmak için kullanılan varsayılan arama yolunu değiştirebilirsiniz. Avantajı, elbette, çalışma zamanında hesaplanan bu işleve dinamik bir değer iletebilmenizdir . Bu DllImport
özellik ile mümkün değildir , bu yüzden orada göreceli bir yol (yalnızca DLL'in adı) kullanacak ve sizin için bulmak için yeni arama sırasına güveneceksiniz.
Bu işlevi P / Çağırmanız gerekir. Bildirge şöyle:
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);