什么是在DLL中,它是如何工作的?

我总是在我的C#代码中引用DLL,但是我仍然想澄清一些问题。 这是关于DLL的问题的一个大脑转储。

我知道一个DLL是一个dynamic链接库,这意味着另一个程序可以在运行时访问这个库来获得“function”。 但是,考虑以下与Web.dllBusiness.dll ASP.NET项目( Web.dll是前端function,它引用Business.dll的types和方法)。

  1. Web.dll在什么时候dynamic链接到Business.dll ? 在使用Word(等等)的时候,你会注意到很多Windows硬盘抖动看起来很小的任务,而且我认为Word会closures,并且dynamic链接到其他DLL的function。

    1A。 另外,什么加载和链接的DLL – 操作系统或一些运行时框架,如.NET框架?

    1B。 什么是“连接”的过程? 是否进行兼容性检查? 加载到相同的内存? 链接究竟意味着什么?

  2. 什么实际上执行DLL中的代码? 它是由处理器执行还是在处理器理解DLL中的代码之前还有另外的翻译或编译阶段?

    2A。 在使用C#.NET构buildDLL的情况下,直接运行.NET框架还是操作系统?

  3. Linux上的DLL是否可以在Windows系统上运行(如果存在这样的情况),还是他们在操作系统?

  4. DLL是特定于特定框架的吗? 使用C#.NET构build的DLL可以由使用Borland C ++构build的DLL使用吗?

    4A。 如果4的答案是“否”,那么DLL的重点是什么? 为什么不是各种框架使用自己的格式链接文件? 例如:.NET中内置的.exe文件知道.abc文件types可以链接到代码中。

  5. 回到Web.dll / Business.dll例子 – 要获得一个类的客户,我需要从Web.dll引用Business.dll 。 这意味着Business.dll包含某种types的规范,即客户类实际上是什么。 如果我已经在Delphi中编译了我的Business.dll文件,那么C#会理解它,并且能够创build一个客户类,或者是否有某种标题信息或者某种表示“嗨,对不起,你只能使用我delphiDLL“?

    5A。 同样适用于方法; 我可以在DLL中编写一个CreateInvoice()方法,用C ++编译它,然后从C#中访问并运行它? 什么停止或允许我这样做?

  6. 关于DLL劫持的问题,当然,replace(坏)DLL必须包含正在被劫持的方法签名和types。 我想这不会很难做,如果你能找出原始DLL中有什么方法可用。

    6A。 什么在我的C#程序是决定我是否可以访问另一个DLL? 如果我的劫持DLL包含完全相同的方法和types的原始,但它是用另一种语言编译的,它会工作吗?

什么是DLL导入和DLL注册?

在这里,我可以随时指出任何错误。 我不完全是Windows内部专家…

首先,你需要了解两种非常不同types的DLL之间的区别。 微软决定使用.NET(托pipe代码)和本地代码来使用相同的文件扩展名(.exe和.dll),但托pipe代码DLL和本机DLL在内部是非常不同的。

1)在什么时候web.dlldynamic链接到business.dll? 你注意到很多在使用Word等看似很小的任务的Windows硬盘驱动器,我认为这个Word会closures,并dynamic链接到其他DLL的function?

1)在.NET的情况下,当第一个方法尝试访问DLL中的任何内容时,通常都会根据需要加载DLL。 这就是为什么如果无法加载DLL,可以在代码中的任何位置获取TypeNotFoundExceptions。 当像Word这样的东西突然开始大量访问硬盘时,可能会交换(将数据交换到磁盘以腾出空间)

1a)另外什么加载和链接的DLL – 操作系统或一些运行时框架,如.Net框架?

1a)对于托pipe的DLL,.NET框架是加载的,JIT编译(将.NET字节码编译为本地代码)并链接DLL。 在本地DLL的情况下,它是操作系统的一个组件,加载和链接DLL(不需要编译,因为本地DLL已经包含本地代码)。

1b)“连接”的过程是什么? 检查是否有兼容性? 加载到相同的内存? 链接究竟意味着什么?

1b)链接是指调用代码中的符号(例如方法)中的引用(例如方法调用)被DLL中的事物的实际地址replace。 这是必要的,因为在DLL被加载到内存之前,DLL中事件的最终地址是不可知的。

2)什么实际上执行DLL中的代码? 它是由处理器执行还是在处理器理解DLL中的代码之前还有另外的翻译或编译阶段?

2)在Windows上,.exe文件和.dll文件完全相同。 本地.exe和.dll文件包含本机代码(处理器执行相同的东西),所以不需要翻译。 托pipe的.exe和.dll文件包含.NET字节码,这是第一个JIT编译(翻译成本地代码)。

2a)在从C#.net构build的DLL的情况下运行这个是什么? .Net框架或操作系统直接?

2a)代码被JIT编译后,它的运行方式与任何代码完全相同。

3)Linux中的DLL是否可以在Windows系统上运行(如果存在这种情况)还是它们是操作系统特定的?

3)只要两个平台上的框架是最新的,并且编写DLL的人不会故意通过使用本地调用破坏兼容性,托pipe的DLL可能会按原样工作。 原生DLL不能作为原样工作,因为格式不同(即使机器内部的代码是相同的,如果它们都是同一个处理器平台的话)。 顺便说一句,在Linux上,“DLL”被称为.so(共享对象)文件。

4)它们是否特定于某个特定的框架? 使用C#.Net构build的DLL是否可以由使用Borland C ++构build的DLL使用(仅用于示例)?

4)托pipe的DLL对于.NET框架来说是特殊的,但是它们自然而然地使用任何兼容的语言。 只要每个人都使用相同的约定(调用约定(函数参数如何在机器代码级别传递),符号命名等),本机DLL就是兼容的。

5)回到web.dll / business.dll的例子。 要获得类客户的types,我需要从web.dll中引用business.dll。 这意味着business.dll包含某种客户类实际上的规范。 如果我已经编译了我的business.dll文件说delphiC#理解它,并能够创build一个客户类 – 或有某种头信息或东西说:“嘿抱歉,你只能从另一个delphi的DLL使用我” 。

5)托pipe的DLL包含他们包含的每个类,方法,字段等的完整描述。 AFAIK Delphi不支持.NET,所以它会创build原生的DLL,它不能直接在.NET中使用。 您可能可以使用PInvoke调用函数,但不能find类定义。 我不使用Delphi,所以我不知道它如何存储与DLL的types信息。 例如,C ++依赖于包含types声明的头文件(.h),并且必须与DLL一起分发。

6)关于DLL劫持的问题,当然,replace(坏)DLL必须包含确切的方法签名,types被劫持。 我想这不是很难做,如果你能找出什么方法等原始DLL中可用。

6)的确,如果您可以轻松切换DLL,这并不难。 代码签名可以用来避免这种情况。 为了让某人replace已签名的DLL,他们必须知道签名密钥,它保密。

6a)这里有一个重复的问题,但是这又回到了我的C#程序正在决定是否可以访问另一个DLL? 如果我的劫持DLL包含完全相同的方法和types的原始,但它是在另一个lanugage编译将工作?

6a)只要它是用任何.NET语言制作的托pipeDLL,它就会工作。

  • 什么是DLL导入? 和DLL注册?

“DLL导入”可能意味着很多东西,通常意味着引用一个DLL文件并使用它。

DLL注册是在Windows上完成的工作,将DLL文件全局注册为COM组件,以使它们可供系统上的任何软件使用。

1)在什么时候web.dlldynamic链接到business.dll? 你注意到很多在使用Word等看似很小的任务的Windows硬盘驱动器,我认为这个Word会closures,并dynamic链接到其他DLL的function?

1)我认为你是加载混淆连接。 链接是当所有的检查和平衡都经过testing,以确保所要求的是可用的。 在加载时,DLL的一部分被加载到内存中或换出到页面文件。 这是你看到的高清活动。

dynamic链接不同于静态链接,因为在静态链接中,链接时所有的目标代码都被放到主要的.exe文件中。 通过dynamic链接,目标代码被放入一个单独的文件(dll)中,并在与.exe不同的时间加载。

dynamic链接可以是隐式的(即应用程序链接到一个导入库),或者显式的(即应用程序使用LoadLibrary(ex)来加载DLL)。

在隐式的情况下,/ DELAYLOAD可以用来推迟DLL的加载,直到应用程序真正需要它。 否则,至less它的某些部分被加载(映射到进程地址空间),作为进程初始化的一部分。 该DLL也可以请求在进程处于活动状态时永远不会被卸载。

COM使用LoadLibrary加载COM dll。 请注意,即使在隐式的情况下,系统正在使用类似于LoadLibrary的东西来加载DLL,无论是在启动过程中还是在第一次使用。

2)什么实际上执行DLL中的代码? 它是由处理器执行还是在处理器理解DLL中的代码之前还有另外的翻译或编译阶段?

2)Dll包含类似.exes的对象代码。 dll文件的格式与exe文件的格式几乎相同。 我听说在这两个文件的头文件中只有一个不同的位。

在使用C#.net构buildDLL的情况下,.Net框架正在运行它。

3)Linux中的DLL是否可以在Windows系统上运行(如果存在这种情况)还是它们是操作系统特定的?

3)DLL是平台特定的。

4)它们是否特定于某个特定的框架? 使用C#.Net构build的DLL是否可以由使用Borland C ++构build的DLL使用(仅用于示例)?

4)如果特别小心或者写了一些额外的胶水代码,Dll可以与其他框架互操作。

当公司销售具有重叠function的多个产品时,Dll非常有用。 例如,我维护一个由30多种不同产品在公司使用的光栅I / O DLL。 如果您安装了多个产品,则可以升级一个dll,将所有产品升级到新的光栅格式。

5)回到web.dll / business.dll的例子。 要获得类客户的types,我需要从web.dll中引用business.dll。 这意味着business.dll包含某种客户类实际上的规范。 如果我已经编译了我的business.dll文件说delphiC#理解它,并能够创build一个客户类 – 或有某种头信息或东西说:“嘿抱歉,你只能从另一个delphi的DLL使用我” 。

5)根据平台,dll的function以各种方式呈现,通过.h文件,.tlb文件或其他方式在.net上。

6)关于DLL劫持的问题,当然,replace(坏)DLL必须包含确切的方法签名,types被劫持。 我想这不是很难做,如果你能找出什么方法等原始DLL中可用。

6)dumpbin / exports和dumbin / imports是在.exe和.dlls上使用的有趣工具

.dll文件包含您可以在您的应用程序中使用的编译代码。

有时候用来编译.dll的工具很重要,有时候不行。 如果您可以在项目中引用.dll,那么使用哪个工具编写.dll的公开函数并不重要。

链接发生在运行时,不像静态链接库,比如你的类,在编译时链接。

你可以把.dll想象成一个黑盒子,它提供了你不想自己编写的应用程序需要的东西。 是的,有人了解.dll的签名可能会创build另一个.dll文件与其中不同的代码,您的调用应用程序不知道区别。

HTH

Dll文件是我们源代码的编译输出。我们在VS或其他工具中编写的东西将被称为源代码。 写完后应该被计算机理解为执行所需的操作。 以便我们执行构build操作,将代码转换为机器级语言。
所以build-ed文件被称为Dll文件。