0

我的问题与 Windows 和 Linux 环境中的动态库加载(“abc.dll”或“abc.so”)有关。

我有一个 dll 或共享内存。我有两个应用程序必须使用这个 dll(abc.dll 或 abc.so)。现在我已将此 dll(abc.dll 或 abc.so)的副本放在它们各自的可执行文件夹中:

/folder-one/app1.exe
/folder-one/abc.dll (resp. abc.so)
/folder-two/app2.exe
/folder-two/abc.dll (resp. abc.so)

现在,当我运行它时,它会从它的& 运行中app1.exe加载abc-library(abc.dll 或 abc.so) 。 现在,当我运行它时,它会从它的& 运行中加载-library(abc.dll 或 abc.so) 。folder-one
app2.exeabcfolder-two

Q-1 现在我的问题是,当两个应用程序都运行时,会加载两个 dll 副本吗?

Loader 将共享库(abc.dll 或 abc.so)加载到 linux 和 windows 环境中的内存中。 http://tldp.org/HOWTO/Program-Library-HOWTO/shared-libraries.html

Q-2 将共享库(abc.dll 或 abc.so)作为各自文件夹中的单独副本是否有缺点?

Q-3 如果我想从两个应用程序加载一个 dll,那么公共位置应该是什么(这样两个应用程序都可以找到它)?

4

2 回答 2

0

Q-1 现在我的问题是,当两个应用程序都运行时,会加载两个 dll 副本吗?

是的,库将被加载两次,因为它们位于不同的位置(并且名称本身不足以使其独一无二)。

Q-2 将(abc.dll 或 abc.so)作为各自文件夹中的单独副本是否有不利之处?

主要内存消耗,因为代码将被复制(当然每个副本都有自己的数据)。这是一种简化,因为共享代码不是强制性的(Linux 和 Windows 之间有所不同)。一般来说,只读部分是共享的,而读/写部分是私有的(然后复制)。

此外,由于加载期间发生的基本开销(内存分配、地址重定位、依赖关系解析等),加载时间会更高。

不要忘记这也适用于每个依赖项(如果它们部署在您正在使用的库的同一文件夹中)。

最后,您应该考虑部署和更新。这可能是一个优点或一个缺点,但不要忘记共享库可以只更新一次,它将升级所有依赖的应用程序;如果仔细完成,这是一个专业人士,但如果更新可以破坏现有代码,那就是一个缺点。可以管理此问题,例如,在名称中包含版本号(当您更改版本时,不授予兼容性)。

Q-3 如果我从两个应用程序加载 dll,那么它应该在公共位置吗?

是的。库由其名称和位置唯一标识。在这种情况下,它不会在内存中加载两次。

于 2013-10-17T12:46:53.783 回答
0

在 Windows 上,如果一个 dll 已经加载,并且您加载了一个具有相同模块名称的 dll,它将返回加载的那个,而无需费心搜索。

在系统搜索 DLL 之前,它会检查以下内容:

如果内存中已经加载了具有相同模块名称的 DLL,则系统将使用加载的 DLL,无论它在哪个目录中。系统不会搜索该 DLL。

正如这个非常长的 MSDN 页面中所描述的(乍一看,它似乎只与 Windows 撕裂应用程序有关,但它确实谈到了桌面模式,我猜它至少从 Win7 没有改变)

但是,我认为这取决于当今很多事情:您是在运行 Windows 商店应用程序、.net dll 还是 win32 dll。我知道.net 使用探测系统来定位 dll。然后您还必须确定您的 dll 是否作为并行组件保存。

过去的记忆,然后是当前目录,然后是路径很容易理解。我认为 Linux 使用这种方法。

于 2013-10-17T14:41:13.893 回答