LoadLibrary文件路徑及windows API相關的文件路徑問題

LoadLibrary


HMODULE WINAPI LoadLibrary(
  _In_  LPCTSTR lpFileName
);


Loads the specified module into the address space of the calling process. The specified module may cause other modules to be loaded.
用此函數來加載動態鏈接庫到內存。
LoadLibrary按照這樣的方式來搜尋文件,先在應用程序所在目錄去找,然後再去系統路徑下找。

所以 Window 用來定位DLL的搜尋路徑 是這樣的:

通過隱式和顯式鏈接,Windows 首先搜索“已知 DLL”,如 Kernel32.dll 和 User32.dll。Windows 然後按下列順序搜索 DLL:

  1. 當前進程的可執行模塊所在的目錄。

  2. 當前目錄。

  3. Windows 系統目錄。GetSystemDirectory 函數檢索此目錄的路徑。

  4. Windows 目錄。GetWindowsDirectory 函數檢索此目錄的路徑。

  5. PATH 環境變量中列出的目錄。



Fully Qualified vs. Relative Paths


完全限定路徑 VS 相對路徑

For Windows API functions that manipulate files, file names can often be relative to the current directory, while some APIs require a fully qualified path. A file name is relative to the current directory if it does not begin with one of the following:

很多文件操作相關的Windows API中,文件名經常是相對當前目錄來說的,而有些API需要完全限定路徑的文件名。如果不想默認爲當前目錄,那麼可以嘗試下面的一些寫法

  • A UNC name of any format, which always start with two backslash characters ("\\"). For more information, see the next section.
  • A disk designator with a backslash, for example "C:\" or "d:\".
  • A single backslash, for example, "\directory" or "\file.txt". This is also referred to as an absolute path.

If a file name begins with only a disk designator but not the backslash after the colon, it is interpreted as a relative path to the current directory on the drive with the specified letter. Note that the current directory may or may not be the root directory depending on what it was set to during the most recent "change directory" operation on that disk. Examples of this format are as follows:

  • "C:tmp.txt" refers to a file named "tmp.txt" in the current directory on drive C.
  • "C:tempdir\tmp.txt" refers to a file in a subdirectory to the current directory on drive C.

對於由磁盤符C:這種形式組成的文件路徑,系統會認爲這個文件位於該磁盤下的當前目錄,如C:temp.txt,temp位於C盤的當前目錄下

A path is also said to be relative if it contains "double-dots"; that is, two periods together in one component of the path. This special specifier is used to denote the directory above the current directory, otherwise known as the "parent directory". Examples of this format are as follows:

  • "..\tmp.txt" specifies a file named tmp.txt located in the parent of the current directory.
  • "..\..\tmp.txt" specifies a file that is two directories above the current directory.
  • "..\tempdir\tmp.txt" specifies a file named tmp.txt located in a directory named tempdir that is a peer directory to the current directory.

我們經常用到點加反向斜槓這種寫法,.\表示當前目錄,即當前工程所在的文件目錄;..\表示當面目錄的上一個目錄,即父目錄。

Relative paths can combine both example types, for example "C:..\tmp.txt". This is useful because, although the system keeps track of the current drive along with the current directory of that drive, it also keeps track of the current directories in each of the different drive letters (if your system has more than one), regardless of which drive designator is set as the current drive.

磁盤符加點跟反向斜槓可以組合,如C:..\tmp.txt",我們雖然限定了磁盤符,但是系統也會去其他磁盤找當面目錄名下的tmp.txt文件。

最後,傳授一個定義一個文件所在目錄的技巧,這裏用到的是define宏。

  1. #define __LIBC_SUFFIX   _T("")  
  2. #define __DBG_SUFFIX    _T("_rd")  
  3.   
  4. #define __DLL_PREFIX    _T("")  
  5. #define __DLL_SUFFIX    _T(".dll")  
  6.   
  7. // 聲明DLL文件名常量  
  8. #define DECLARE_DLL_FILE(module) \  
  9.     extern "C" const TCHAR* module;  
  10.   
  11. #define MAKE_LIB_NAME(module)\  
  12.     _T(#module)_T("")__LIBC_SUFFIX _T("")  
  13.   
  14. // 定義DLL文件所在目錄  
  15. #define DEFINE_DLL_FILE(module) \  
  16.     extern "C" const TCHAR* module = _T("./")_T("")__DLL_PREFIX _T("")MAKE_LIB_NAME(module)_T("")__DLL_SUFFIX;  
  17.   
  18. DECLARE_DLL_FILE(dllthree);  
  19. DEFINE_DLL_FILE(dllthree);  

上面的define展開後,文件名爲  ./dllthree.dll  系統會去應用程序所在目錄去找這個dll文件。 這樣以後,LoadLibrary(dllthree)就可以直接加載文件名爲dllthree.dll的動態鏈接庫了。

嘗試後,有下面幾種方式

  1. //HMODULE m_h = ::LoadLibrary(_T("..//bin//dllthree.dll"));  
  2.   
  3. //HMODULE m_h = ::LoadLibrary(_T("..\\bin\\dllthree.dll"));  
  4.   
  5. //HMODULE m_h = ::LoadLibrary(_T("../bin/dllthree.dll"));  
  6.   
  7. //HMODULE m_h = ::LoadLibrary(_T("..\bin\dllthree.dll")); //wrong  
  8.   
  9. //HMODULE m_h = ::LoadLibrary(_T(".\dllthree.dll")); //wrong  

後面兩種搜尋不到。暫時對這幾種路徑表示方式表示觀望態度。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章