Windows 下 DLL 的搜索路径

过程中遇到了 UNICODE与ANSI 两种配置的问题并解决。

我的代码:

wchar_t* string2LPCWSTR(string str)  { size_t size = str.length(); wchar_t *buffer = new wchar_t[size+1]; MultiByteToWideChar( CP_ACP, 0, str.c_str(), size, buffer, size * sizeof(wchar_t) ); buffer[size] = 0;  return buffer; } BOOL SetCurrentEnvPath() {  char chBuf[0x8000]={0}; wchar_t* LchBuf = string2LPCWSTR(chBuf); //LPWSTR LchBuf = CA2W(chBuf); DWORD dwSize =GetEnvironmentVariable(_T("PATH"),LchBuf,0x10000); CString strEnvPaths(LchBuf);   // 将当前路径\dll路径添加到本进程的路径中   if(!::GetModuleFileName(NULL,LchBuf,MAX_PATH))   return FALSE;   CString strAppPath(LchBuf); /*LPTSTR str = strAppPath.GetBuffer(0); strAppPath.ReleaseBuffer(); char *pFileName =(char *)malloc( 2*wcslen(str)+1 ); wcstombs(pFileName , str, 2*wcslen(str)+1 );  printf("%s",pFileName);*/ const int nPos = strAppPath.ReverseFind(_T('\\'));   if(nPos>0){   // 路径中包含最后的'\\'   strAppPath = strAppPath.Mid(0,nPos+1);   } strEnvPaths.TrimRight(_T(";")); strEnvPaths += ";" + strAppPath +"KJ";   BOOL bRet = SetEnvironmentVariable(_T("PATH"),strEnvPaths); LPTSTR str = strEnvPaths.GetBuffer(0); strEnvPaths.ReleaseBuffer(); char *pFileName =(char *)malloc( 2*wcslen(str)+1 ); wcstombs(pFileName , str, 2*wcslen(str)+1 );  printf("%s",pFileName); return true;   }  

网上摘录的方法:

在开发软件时,碰到了有一大批的dll需要加载,且这些dll中有隐式链接到其它dll情况.由于某些原因,不能将dll放入系统目录中也不能将他们放置在应用程序同一目录中.

为集中管理,将其放置到应用程序目录下的字目录MyDllPath目录下.
当使用LoadLibrary加载dll时会由于dll中存在隐式链接,且被链接的dll不在当前路径下(在MyDllPath路径下)而导致加载失败的情况.
这时,可以使用GetEnvironmentVariable/SetEnvironmentVariable来调整本应用程序的路径设定.将MyDllPath加载到本应用程序的当前路径中.这样即可正常加载所需要的dll了.
如下是修改当前应用程序目录路径的方法:
BOOL SetCurrentEnvPath()  
{  
    char chBuf[0x8000]={0};  
    DWORD dwSize =GetEnvironmentVariable("path",chBuf,0x10000);  
    CString strEnvPaths(chBuf);  
  
    // 将当前路径\dll路径添加到本进程的路径中  
    if(!::GetModuleFileName(NULL,chBuf,MAX_PATH))  
        return FALSE;  
    CString strAppPath(chBuf);  
    const int nPos = strAppPath.ReverseFind(_T('\\'));  
    if(nPos>0){  
        // 路径中包含最后的'\\'  
        strAppPath = strAppPath.Mid(0,nPos+1);  
    }  
  
    strEnvPaths.TrimRight(";");  
    strEnvPaths += ";" + strAppPath +"MyDllPath;";  
  
    BOOL bRet = SetEnvironmentVariable("path",strEnvPaths);  
  
    return bRet;  
}  
根据MSDN.应用程序在加载dll时,所搜索的路径如下(Windows 2000/NT):
The directory from which the application loaded.
The current directory.
The system directory. Use the GetSystemDirectory function to get the path of this directory.
The 16-bit system directory. There is no function that obtains the path of this directory, but it is searched.
The Windows directory. Use the GetWindowsDirectory function to get the path of this directory.
The directories that are listed in the PATH environment variable.

《Windows 核心编程(第5版)》P522 

19.2.3 运行可执行模块:

由于导入段只包含 DLL 的名称,不包含 DLL 的路径,因此加载程序必须在用户的磁盘上搜索 DLL。下面是加载程序的搜索顺序:

(1) 包含可执行文件的路径;

(2) Windows 的系统目录,该目录通过 GetSystemDirectory 得到; 

(3) 16 位的系统目录,即 Windows 目录中的 system 子目录; 

(4) Windows 目录,该目录可通过 GetWindowsDirectory 得到;

(5) 进程的当前目录;

(6) PATH 环境变量中所列出的目录。

 

测试环境: Win7U + VS2008SP1 

上面顺序中的路径分别理解为:

【1】 VS2008生成的测试用 .exe 文件所在目录;

【2】 C:/Windows/system32; 

【3】 C:/Windows/system; 

【4】 C:/Windows; 

【5】 VS2008 中工程文件所在目录(.vcproj 文件所在目录,即工程默认路径); 

【6】 PATH 环境变量中所列出任一目录。 

 

经过测试,搜索顺序是从【1】到【6】的优先级。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值