zoukankan      html  css  js  c++  java
  • 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 mp.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:

    • ".. mp.txt" specifies a file named tmp.txt located in the parent of the current directory.
    • ".... mp.txt" specifies a file that is two directories above the current directory.
    • ".. empdir mp.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:.. mp.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:.. mp.txt",我们虽然限定了磁盘符,但是系统也会去其他磁盘找当面目录名下的tmp.txt文件。

    最后,传授一个定义一个文件所在目录的技巧,这里用到的是define宏。

     

    #define __LIBC_SUFFIX	_T("")
    #define __DBG_SUFFIX	_T("_rd")
    
    #define __DLL_PREFIX	_T("")
    #define __DLL_SUFFIX	_T(".dll")
    
    // 声明DLL文件名常量
    #define DECLARE_DLL_FILE(module) 
    	extern "C" const TCHAR* module;
    
    #define MAKE_LIB_NAME(module)
    	_T(#module)_T("")__LIBC_SUFFIX _T("")
    
    // 定义DLL文件所在目录
    #define DEFINE_DLL_FILE(module) 
    	extern "C" const TCHAR* module = _T("./")_T("")__DLL_PREFIX _T("")MAKE_LIB_NAME(module)_T("")__DLL_SUFFIX;
    
    DECLARE_DLL_FILE(dllthree);
    DEFINE_DLL_FILE(dllthree);


    上面的define展开后,文件名为  ./dllthree.dll  系统会去应用程序所在目录去找这个dll文件。 这样以后,LoadLibrary(dllthree)就可以直接加载文件名为dllthree.dll的动态链接库了。


    尝试后,有下面几种方式

     

    //HMODULE m_h = ::LoadLibrary(_T("..//bin//dllthree.dll"));
    
    //HMODULE m_h = ::LoadLibrary(_T("..\bin\dllthree.dll"));
    
    //HMODULE m_h = ::LoadLibrary(_T("../bin/dllthree.dll"));
    
    //HMODULE m_h = ::LoadLibrary(_T("..indllthree.dll")); //wrong
    
    //HMODULE m_h = ::LoadLibrary(_T(".dllthree.dll")); //wrong
    

    后面两种搜寻不到。暂时对这几种路径表示方式表示观望态度。
  • 相关阅读:
    拟真世界精密驾驶挑战 《微软飞行模拟》新截图放出
    抖音“统治”美国年轻人
    Google Play商店为预注册的游戏和应用提供自动安装功能
    小米Note 10 Lite海外发布 无缘中国市场
    亚马逊允许数万名员工在家工作直到10月2日
    刷新 翻看 我 关注 实时 疫情 何时彻底“解封”?王辰院士:北京防疫未到松懈时
    “胡汉三”饰演者刘江今晨去世,享年95岁
    虎牙年报披露2019年扭亏为盈,腾讯操持下与斗鱼合并倒计时?
    微软宣布一批新获得Microsoft Teams认证的会议硬件
    美版健康码要来了!苹果Google被网友质疑:这是变相的监视系统吗?
  • 原文地址:https://www.cnblogs.com/pangblog/p/3241536.html
Copyright © 2011-2022 走看看