在DLL中动态加载其所依赖的dll
windows下LoadLibrary函数的搜索顺序是先搜索system32等系统环境变量path下注册过的路径,然后是当前路径。
这里的相对路径是指的主exe所在路径,并且相对路径在程序运行过程中可能会发生变化。
所以,这里就有一个坑:
1,对于普通的x.dll,一般都是和x.exe在同一个目录下,x.exe直接LoadLibrary x.dll 即可;
2,对于普通的x.dll依赖的xdep.dll,一般两个dll也是与x.exe在同一个目录下,x.dll直接LoadLibrary xdep.dll也行;
3,对于COM的x.dll,直接LoadLibrary就不行了,因为x.dll是需要注册的,x.dl和xcomdep.dll的路径不一定与x.exe在同一个目录下,这样x.dll中使用LoadLibrary xcomdep.dll将失败,因为x.dll中得到的相对路径是x.exe的相对路径,而x.exe路径下面并没有xcomdep.dll。
对于这个问题,可以用下面的一些函数解决:
//获取当前dll的句柄
HMODULE GetCurrentDllModule()
{
MEMORY_BASIC_INFORMATION m = {};
VirtualQuery(GetCurrentDllModule, &m, sizeof(MEMORY_BASIC_INFORMATION));
return (HMODULE) m.AllocationBase;
}
//获取当前dll的全路径
//如 : e:\test\test.dll
void GetCurrentDllPath(WCHAR* lpwDllPath)
{
HMODULE hThisMod = GetCurrentDllModule();
GetModuleFileNameW(hThisMod,lpwDllPath,MAX_PATH);
}
//获取当前dll的路径
//如 : e:\test\
void GetCurrentDllRoute(WCHAR* lpwDllRoute)
{
GetCurrentDllPath(lpwDllRoute);
WCHAR* lpwPos = wcsrchr(lpwDllRoute,L'\\');
*(lpwPos+) = L'\0';
}
//获取与当前dll相同目录的依赖dll的全路径
//如 : 当前dll依赖于同目录下的test_dep.dll
// 结果为:e:\test\test_dep.dll
void GetDepdenceDllPath(const WCHAR* lpcwDepDllName,WCHAR* lpwDepDllPath)
{
GetCurrentDllRoute(lpwDepDllPath);
wcscat(lpwDepDllPath,lpcwDepDllName);
}
//动态加载与dll同目录下的dll
HMODULE LoadDepDll(const WCHAR* lpcwDepDllName)
{
WCHAR lpwDepDllPath[MAX_PATH];
GetDepdenceDllPath(lpcwDepDllName,lpwDepDllPath);
return ::LoadLibraryW(lpwDepDllPath);
}
在DLL中动态加载其所依赖的dll的更多相关文章
- Java之——Web项目中DLL文件动态加载方法
本文转自:https://blog.csdn.net/l1028386804/article/details/53903557 在Java Web项目中,我们经常会用到通过JNI调用dll动态库文件来 ...
- C#.Net 如何动态加载与卸载程序集(.dll或者.exe)0-------通过应用程序域AppDomain加载和卸载程序集
本博客中以“C#.Net 如何动态加载与卸载程序集(.dll或者.exe)”开头的都是引用莫问奴归处 微软装配车的大门似乎只为货物装载敞开大门,却将卸载工人拒之门外.车门的钥匙只有一把,若要获得还需要 ...
- C#.Net 如何动态加载与卸载程序集(.dll或者.exe)3---- 动态加载Assembly应用程序
下载 supergraphfiles.exe 示例文件. 应用程序体系结构 在我专攻代码之前,我想谈谈我尝试做的事.您可能记得,SuperGraph 让您从函数列表中进行选择.我希望能够在具体的目录中 ...
- Delphi静态加载DLL和动态加载DLL示例
下面以Delphi调用触摸屏动态库xtkutility.dll为例子,说明如何静态加载DLL和动态加载DLL. 直接上代码. 1.静态加载示例 unit Unit1; interface uses W ...
- 在VC中动态加载ODBC的方法
在使用VC.VB.Delphi等高级语言编写数据库应用程序时,往往需要用户自己在控制面板中配置ODBC数据源.对于一般用户而言,配置ODBC数据源可能是一件比较困难的工作.而且,在实际应用中,用户往往 ...
- 某APK中使用了动态注册BroadcastReceiver,Launcher中动态加载此APK出现java.lang.SecurityException异常的解决方法
在某APK中,通过如下方法动态注册了一个BroadcastReceiver,代码参考如下: @Override protected void onAttachedToWindow() { super. ...
- 在ASP.NET中动态加载内容(用户控件和模板)
在ASP.NET中动态加载内容(用户控件和模板) 要点: 1. 使用Page.ParseControl 2. 使用base.LoadControl 第一部分:加载模板 下 面是一个模板“<tab ...
- 在MVC应用程序中动态加载PartialView
原文:在MVC应用程序中动态加载PartialView 有时候,我们不太想把PartialView直接Render在Html上,而是使用jQuery来动态加载,或是某一个事件来加载.为了演示与做好这个 ...
- WPF中动态加载XAML中的控件
原文:WPF中动态加载XAML中的控件 using System; using System.Collections.Generic; using System.Linq; using System. ...
随机推荐
- 判断浏览器是否支持 JS
在有些浏览器中不支持(或者被禁用了)脚本语言,那么javascript脚本则无法被执行.但是用户并不知道浏览器是否支持,或者被禁用.我们可以通过<noscript>标签来告知用户,JS脚运 ...
- Druid和Spark对比
Druid和Spark对比 不是Spark专家, 如果描绘有错误, 请通过邮件列表或者其他方式告知我们 Spark实现弹性的分布式数据集概念的计算集群系统, 可以看做商业分析平台. RDDs能复用持久 ...
- Netty4 initAndRegister 解析
我们从框架的应用层面来分析,NioEventLoopGroup在netty中的使用. 这是我们需要配置的地方. 紧接着我们进入netty的运行中.ServerBootstrap.bind(PORT); ...
- 基础普及-Jar、War、Ear
名词解释 Jar文件(扩展名为. Jar) 包括Java类的普通库.资源(resources).辅助文件 (auxiliary files)等 War文件(扩展名为.War) 包括所有Web应用程序. ...
- 插件化注解处理API(Pluggable Annotation Processing API)
Java奇技淫巧-插件化注解处理API(Pluggable Annotation Processing API) 参考资料 JDK6的新特性之六:插入式注解处理API(Pluggable Annota ...
- java 发送html邮件,苹果或者某些邮件客户端收到的内容为空白解决方案
需要把网页标签中的双引号替换为 " 或者 \\\" 例如 <div id=\\\"container\\\" style=\\\"widt ...
- web 前端 常见操作 将时间戳转成日期格式 字符串截取 使用mui制作选项卡
1.将时间戳转成日期格式: //第一种 function getLocalTime(nS) { return new Date(parseInt(nS) * 1000).toLocaleString( ...
- 《Java程序猿面试笔试宝典》之Statickeyword有哪些作用
statickeyword主要有两种作用:第一,仅仅想为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关.第二,希望某个方法或属性与类而不是对象关联在一起,也就是说,在不创建对象的情况下 ...
- (一)Redis笔记——简介 、key 、数据类型
1. Redis是什么.特点.优势 Redis是一个开源的使用C语言编写.开源.支持网络.可基于内存亦可持久化的日志型.高性能的Key-Value数据库,并提供多种语言的API. 它通常被称为数据结 ...
- linux归档压缩命令
1.tar tar -cf output.tar file1.txt file2.txt .. tar -rvf output.tar fl ...