当前位置: 首页 > 面试题库 >

(静态链接的)DLL是否使用与主程序不同的堆?

赵选
2023-03-14
问题内容

我是Windows编程的新手,我只是迷失了两个小时来寻找每个人似乎都知道的错误:您不能在DLL的堆上创建对象,而在另一个DLL(或主程序)中销毁它。

我几乎可以肯定,在Linux / Unix上不是这种情况(如果可以,请说出来,但是我敢肯定,我做了数千次都没有问题……)。

在这一点上,我有两个问题:

1)静态链接的DLL是否使用与主程序不同的堆?

2)静态链接的DLL是否映射在主程序的相同进程空间中?(我非常确定,这里的答案是肯定的,否则将指针从主程序中的函数传递到DLL中的函数就没有意义了)。

我说的是普通/常规DLL,而不是COM / ATL服务

编辑:通过“静态链接”我的意思是我不使用LoadLibrary加载DLL,但我与存根库链接


问题答案:

DLL / exes将需要链接到C运行时库的实现。

对于C Windows运行时库,如果希望链接到以下内容,则可以选择指定:

  1. 单线程C运行时库(现已停止对单线程库的支持)
  2. 多线程DLL /多线程调试DLL
  3. 静态运行时库。
  4. 更多(您可以检查链接)

它们中的每一个都将引用一个不同的堆,因此不允许您从一个运行时库的堆获得的地址传递给另一个。

现在,它取决于您所讨论的DLL已链接到哪个C运行时库。假设,您正在使用的DLL已链接到静态C运行时库,而您的应用程序代码(包含主函数)已链接到多线程C运行时DLL,那么如果您将指针传递给在DLL到您的主程序,然后尝试将其释放,反之亦然,这可能导致未定义的行为。因此,根本原因是C运行时库。请仔细选择它们。

请在此处和此处找到有关支持的C运行时库的更多信息

来自MSDN的报价:

注意 请勿混合使用静态版本和动态版本的运行时库。
进程中有多个运行时库副本可能会导致问题,因为一个副本中的静态数据不会与另一副本共享。链接器可防止您同时链接一个.exe文件中的静态版本和动态版本,但最终仍可以得到两个(或更多)运行时库副本。例如,与运行时库的动态(DLL)版本链接的.exe文件一起使用时,与运行时库的静态(非DLL)版本链接的动态链接库可能会导致问题。
。(您还应避免在一个过程中混合使用库的调试版本和非调试版本。)



 类似资料:
  • 问题内容: 我一直在尝试将Obj-C库移植到Swift,但是遇到了一个问题,当Swift代码在项目中时,链接器无法构建静态库。 作为最小的复制者,请进入XCode6并创建一个新的iOS静态库。它会为您提供一个带有空白.h和.m文件的项目。这样可以编译良好。然后,将新的.swift文件添加到项目中(无论是否创建标题桥)。这也 应该 编译良好,但是在链接期间失败: 如果我瞄准模拟器或设备,则会发生这种

  • 问题内容: 在Linux中,下载了程序源并希望将其静态链接。我那里有一个巨大的Makefile 编译。预言这有点太笼统了,但是如何使二进制文件静态链接? 编辑:这样做的原因是要确保二进制文件没有依赖性(或至少尽可能少),从而使其可以在任何基于Linux的计算机上运行,​​甚至可以在没有Internet连接和未更新的Linux上运行。 问题答案: 大多数生成的脚本将允许您进行静态构建: 如果这样不起

  • 问题内容: 假设我在Linux中有一个使用共享库(文件)的应用程序。我的问题是这些库中的代码是否将在与主应用程序相同的堆中分配内存,还是使用自己的堆? 因此,例如,文件中的某些函数调用,它将使用与应用程序相同的堆管理器,还是使用另一个应用程序?同样,那些共享内存中的全局数据又如何呢?它在哪里?对于应用程序,我知道它位于bss和数据段中,但是不知道这些共享对象文件在哪里。 问题答案: 我的问题是这些

  • 主要内容:静态链接库,动态链接库,总结我们知道,C、C++程序从源文件到生成可执行文件需经历 4 个阶段,分别为预处理、编译、汇编和链接,本节将重点围绕链接阶段,对静态链接库和动态链接库做详细的讲解。 有关链接操作的具体细节,感兴趣的读者可阅读《 到底什么是链接,它起到了什么作用?》和《 符号——链接的粘合剂》这两节。总的来说链接阶段要完成的工作,就是将同一项目中各源文件生成的目标文件以及程序中用到的库文件整合为一个可执行文件。 通过

  • 问题内容: Java 8之前的Java版本要求本机代码必须位于共享库中,但是我已经读到Java 8可以在JNI中使用静态链接库。我已经搜索了示例,但找不到任何示例。 如何将JNI库静态链接到Java应用程序? 问题答案: Java SE 8规范已更改为支持静态链接,并且静态链接在JDK中实现。在System.loadLibrary的规范中对此进行了简要介绍。它所引用的JNI规范的各个部分在此处和此

  • 问题内容: 我正在编写一个与GNU GPL不兼容的跨平台应用程序。我当前面临的主要问题是该应用程序与glibc和libstdc ++动态链接,并且几乎所有对库的新更新都不向后兼容。因此,在我的应用程序中会看到随机崩溃。 解决方法是,将应用程序的二进制文件分发在几个不同的系统(具有不同的C / C 运行时版本)上编译。但我要没有这个。所以我的问题是,请牢记许可和所有注意事项,我可以静态链接glibc