如何从流中加载非托管 DLL?

4

我有一个使用.NET 4.0编写的应用程序,需要在内存中加载一个本地DLL(使用C语言编写)。

目前,我正在使用P/Invoke调用LoadLibrary,传递DLL所在的路径。

虽然这种方法可行,但由于这个DLL来自数据库,因此我想知道是否可以通过流加载它,从而避免将DLL存储在文件系统中的必要性。


你可以在本地应用程序中实现它,因此理论上你可以在.NET中重写它。https://www.joachim-bauch.de/tutorials/loading-a-dll-from-memory/ - toster-cx
2个回答

2

Windows不允许这样做,本机代码必须始终从磁盘上的文件加载。这是操作系统设计的核心,可执行文件通过内存映射文件映射到内存中,这需要一个文件。

对于纯托管代码(Assembly.Load(byte[])),它可以工作,因为IL是数据,而不是本机代码。

避免将DLL存储在数据库中,您通常不能将其写入磁盘,因为UAC、病毒扫描器或IT工作人员会对突然出现的可执行文件感到非常不满。它可以在开发环境中运行,但用户机器上的机率很低。


该应用程序非常复杂,已经设计为在特定环境中运行。感谢您提供的信息,我将继续提取到文件系统中。 - Drake
这是错误的。你可以从内存中加载DLL,这被称为手动映射。 - Felix Lebel
Felix,请问你能解释一下如何做这个吗? - ygoe

0

这是不可能的,因为您在 PInvoke 属性用法中指定了文件名。PInvoke 需要一个静态已知的文件名。

如果您无法静态决定文件名,您可能需要使用 LoadLibrary 和 GetProcAddress 调用 dll 中包含的函数。

或者您可以使用反射发射来动态发射 PInvoke 函数。


除了LoadLibrary之外,是否存在其他API可用于从流中加载DLL到内存中? - Drake
不存在这样的API。许多Windows API,以及可能是内核,都期望加载的库基于内存映射文件。 - usr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接