`

VC++自定义加载DLL,从任意位置加载依赖的DLL

    博客分类:
  • VC++
阅读更多

摘自:https://blog.csdn.net/cp1300/article/details/53420444

 

这里讲了一些关于反射的知识,我没有接触过所以看不懂,但我认为这可能是一个很有用知识点很深的文章,所以记录下来。

 

隐藏VS开发的程序目录下的DLL,可以将依赖的DLL放到指定位置去。

 

1.一直使用第三方控件,编译后依赖的控件都在运行目录,或者system32目录,看的很别扭,寻找过很多方法重定义加载,发现太复杂,最后无意间使用反射时发现,同一个DLL放在不同的地方只会被加载一次,因为每个dll都有一个唯一的KEY,利用这个方法,人为的加载这些DLL,可以从任意位置加载,可以解决程序运行目录下一堆DLL文件的问题。

这个方法只适用于反射方式加载的控件所依赖的DLL,不能对直接引用的DLL进行预加载。

 

  1.  
    //初始化加载一些用到的DLL文件
  2.  
    try
  3.  
    {
  4.  
    System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() + "\\DLL\\DevComponents.DotNetBar2.dll"); //加载DLL
  5.  
    System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() + "\\DLL\\DevExpress.Data.v14.2.dll"); //加载DLL
  6.  
    System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() + "\\DLL\\DevExpress.Utils.v14.2.dll"); //加载DLL
  7.  
    System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() + "\\DLL\\DevExpress.XtraEditors.v14.2.dll"); //加载DLL
  8.  
    System::Reflection::Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() + "\\DLL\\IPAddressControlLib.dll"); //加载DLL
  9.  
    }
  10.  
    catch (System::IO::FileNotFoundException^ e)
  11.  
    {
  12.  
    System::Windows::Forms::MessageBox::Show(e->Message, "加载控件错误,可能无法进行配置!",
  13.  
    System::Windows::Forms::MessageBoxButtons::OK, System::Windows::Forms::MessageBoxIcon::Error);
  14.  
    }

 

2.对直接依赖以及引用的DLL进行加载。

CLR会自动从运行目录或system32加载DLL,如果没有找到就会触发 AssemblyResolve 事件,在此事件中就可以自己去加载需要的DLL文件,返回给CLR.

 

using namespace System::Reflection;

  1.  
    Assembly^ MyResolveEventHandler(Object^ sender, ResolveEventArgs^ args); //申明
  2.  
    [STAThreadAttribute]
  3.  
    int main(array<System::String ^> ^args)
  4.  
    {
  5.  
    AppDomain^ currentDomain = AppDomain::CurrentDomain;
  6.  
     
  7.  
    // 在创建任何控件之前启用 Windows XP 可视化效果
  8.  
    Application::EnableVisualStyles();
  9.  
    Application::SetCompatibleTextRenderingDefault(false);
  10.  
     
  11.  
     
  12.  
    currentDomain->AssemblyResolve += gcnew ResolveEventHandler(MyResolveEventHandler);
  13.  
     
  14.  
     
  15.  
    // 创建主窗口并运行它
  16.  
    Application::Run(gcnew Form1());
  17.  
     
  18.  
    return 0;
  19.  
    }
  20.  
     
  21.  
     
  22.  
     
  23.  
    //缺少DLL文件加载的事件
  24.  
    static Assembly^ MyResolveEventHandler(Object^ sender, ResolveEventArgs^ args)
  25.  
    {
  26.  
     
  27.  
    String ^dll_name;
  28.  
    AssemblyName^ myAssemblyName =
  29.  
    gcnew AssemblyName(args->Name);
  30.  
    Console::WriteLine("Resolving..." + myAssemblyName->Name);
  31.  
    dll_name = myAssemblyName->Name;
  32.  
    if (dll_name->IndexOf(".resources") < 0) //一个DLL文件会产生2次事件,比如abc.dll 第一次是abc,需要自己添加DLL扩展名,第二次会需要abc.resources,此时返回为空即可
  33.  
    {
  34.  
    dll_name += ".DLL";
  35.  
    }
  36.  
    else return nullptr; //resources返回为空即可
  37.  
     
  38.  
    return Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() + "\\DLL\\" + dll_name);
  39.  
    }

 

Assembly::LoadFrom(USER_LIB.GetAppRunningDirectory() + "\\DLL\\" + dll_name);

这个就是从指定的位置加载DLL,可以更换为你自己定义的目录或者从资源文件中加载。

 

分享到:
评论

相关推荐

    VC++动态加载DLL例子

    本示例将深入探讨如何在VC++环境中利用C++语言动态地加载DLL,并在对话框模式下使用其功能。动态加载DLL与静态加载不同,它允许程序在运行时决定是否以及何时加载DLL,这提供了更大的灵活性。 首先,我们需要了解几...

    VC++动态调用DLL实列

    在这个"VC++动态调用DLL实例"中,我们将探讨如何在VC++项目中通过编程方式来加载和使用DLL。 首先,我们需要理解动态调用DLL与静态链接的区别。静态链接是在编译时将所需的库函数直接嵌入到可执行文件中,而动态...

    解开VC++调用.Net DLL的神秘面纱

    总结来说,VC++调用.NET DLL的关键在于正确声明.NET方法,加载DLL,以及适当地处理类型和异常。这种技术在需要结合两种语言优点的项目中非常有用,例如利用.NET的高级特性(如LINQ、反射)和C++的高性能计算。通过...

    VC++创建Dll与显示加载Dll

    本教程将深入探讨如何使用VC++创建DLL以及如何显式加载DLL。 首先,我们来理解DLL的基本概念。DLL是一种可执行文件,它包含可由多个应用程序同时使用的函数和资源。这种共享机制减少了内存占用,简化了软件维护,并...

    VC++加载DLL

    ### VC++加载DLL详解 #### 一、概述 在软件开发过程中,动态链接库(Dynamic Link Library,简称DLL)是一种非常重要的技术手段。通过DLL,开发者可以实现代码重用、功能扩展等多种目的,并有助于减少内存占用及...

    windows下用VC++编写DLL,并在exe中加载DLL使用其中的API的示例源代码

    windows下用VC++编写DLL,并在exe中加载DLL使用其中的API的示例源代码 本文实现了用UDP协议传输传输文件 UDP传1GB的文件仅需15秒 该代码包含 根据文件内容长度生成MD5码,以供校验文件完整性 本代码包含windows vc++...

    VC++生成DLL与静态加载DLL代码

    本篇文章将深入探讨如何使用VC++生成DLL以及如何在控制台应用程序中静态加载DLL。 首先,生成DLL的步骤如下: 1. **创建DLL项目**:在Visual Studio中,选择“新建项目”,然后在C++类别下找到“Win32”项目模板。...

    易语言从内存加载DLL源码

    1. **提高安全性**:避免了DLL文件被恶意篡改或替换,因为程序直接从内存中获取DLL,不依赖于硬盘上的文件。 2. **优化性能**:减少了磁盘I/O操作,提高了程序的运行速度,特别是在大型应用或频繁调用DLL的情况下。...

    易语言内存加载dll模块

    本文将深入探讨“易语言内存加载DLL模块”这一主题,讲解如何在易语言中实现动态链接库(DLL)的内存加载、动态调用、静态调用以及卸载,帮助开发者更好地理解和应用这一技术。 首先,我们需要了解DLL是什么。DLL是...

    DLL_Class.rar_Class Dll_VC++ dll_dll 制作_mapgis_visual c

    描述提到“mapgis6.2二次开发的dll,vc++6.0制作”,这意味着内容将涉及如何利用Visual C++ 6.0作为开发工具,为MapGIS 6.2这个GIS(地理信息系统)软件创建自定义扩展功能。MapGIS 6.2是一个广泛使用的GIS平台,允许...

    VC++ 获取任意DLL/EXE文件属性信息

    在VC++编程环境中,获取DLL或EXE文件的属性信息是一项常见的任务,这涉及到系统级的文件操作和信息解析。本文将深入探讨如何利用VC++实现这一功能,重点关注如何获取文件的基本信息,如名称,以及更高级的特性,如...

    内存加载DLL运行

    在内存加载DLL时,我们不通过传统的`LoadLibrary`或`GetProcAddress`函数直接从磁盘加载,而是将DLL的二进制数据直接读入内存,然后通过API调用来执行其内部的函数。 MemLoadDll.cpp 和 MemLoadDll.h 文件很可能是...

    vc++自删除DLL

    总结来说,"vc++自删除DLL"是一个使用VC++实现的示例,展示了如何在DLL完成其功能后自动从系统中删除自身。通过研究这个项目,开发者可以学习到DLL的加载、使用、以及文件操作等关键知识点,这些对于提升Windows编程...

    VB中调用VC++开发的DLL

    1. **创建VC++ DLL**:在VC++环境中创建一个新的DLL项目,编写所需的函数。在C++代码中,你需要使用`__declspec(dllexport)`关键字来导出函数,以便其他程序可以调用。例如: ```cpp #ifdef MYDLL_EXPORTS #...

    内存加载dll-内存加载dll.rar

    4.2 兼容性:不正确的DLL加载可能导致程序崩溃或功能异常,特别是当依赖的API版本不兼容时。 4.3 性能:虽然内存加载DLL可以减少磁盘I/O,但在大量或频繁的加载操作下,可能会增加系统的内存压力。 总结,内存加载...

    Windows10下Qt动态/静态加载DLL

    在Windows 10环境下开发基于Qt的应用程序时,有时我们需要加载外部动态链接库(DLL)以扩展功能或实现特定操作。动态加载DLL可以提供更大的灵活性,因为它允许在运行时加载和卸载库,而不必在编译时将其链接到应用...

    C# WinForm 动态加载DLL 通过配置文件

    动态加载库可以提高代码的灵活性,减少对应用程序的依赖性,使得更新或扩展功能变得更为便捷。下面将详细介绍如何在C# WinForm程序中通过配置文件实现DLL的动态加载。 首先,我们需要理解什么是DLL(Dynamic Link ...

    C# WinForm动态加载DLL通过配置文件

    动态加载DLL的好处在于,它允许程序在运行时根据需要加载特定功能,而不是在编译时硬编码这些依赖。这种方式提高了代码的模块化和可维护性,同时也方便了软件更新和版本控制。本知识点将深入探讨如何在C# WinForm...

    VC++允许库合集,解决未能加载文件或程序集CefSharp.Core.dll问题

    总之,"VC++允许库合集"是解决C++应用程序依赖问题的关键,而“未能加载文件或程序集CefSharp.Core.dll”通常是由于缺少运行库支持或配置不当所致。通过正确安装和配置VC++运行库,以及检查CefSharp的部署情况,通常...

    delphi内存加载dll(支持xe2)

    3. **解析导入表**:DLL中的函数调用依赖于导入表,你需要手动解析这个表,找到并处理所有导入的函数和依赖项。 4. **设置入口点**:DLL的入口点函数(通常是`DllMain`)在内存中被调用,以执行初始化逻辑。你需要...

Global site tag (gtag.js) - Google Analytics