【问题标题】:How does DllImport in ASP.Net look for the DLL?ASP.Net 中的 DllImport 如何查找 DLL?
【发布时间】:2023-03-15 06:05:01
【问题描述】:

它是否在某处记录了 ASP.Net 如何为本地 DLL 设置搜索路径?我需要能够在我自己的代码中复制逻辑。

了解更多背景信息:我正在维护一个托管库(例如 Managed.DLL),它封装了一个本地库(例如 Native.DLL),而后者又使用另一个本地 DLL(例如 Driver.DLL)。到目前为止,Managed.DLL 一直在使用 .Net 的 DllImport 属性从 Native.DLL 导入函数,但现在我必须将其更改为对 LoadLibrary 和 GetProcAddress 的手动编码调用以获得更多控制;特别是,我需要能够调用 FreeLibrary 来卸载 Native.DLL,而当通过 DllImport 加载 Native.DLL 时我不能这样做。

问题来了:虽然仅 DllImport("Native.DLL") 就足以定位 Native.DLL 和 Driver.DLL,但在使用 Managed.DLL 时调用 LoadLibrary("Native.DLL") 失败并显示 ERROR_FILE_NOT_FOUND在 ASP.Net 应用程序中,因为包含 Managed.DLL 的目录不在本机代码 DLL 的搜索路径中。

我的第一个想法是使用 Assembly.GetExecutingAssembly().Location 然后发出带有完整路径的 LoadLibrary 调用,但是 Native.DLL 找不到 Driver.DLL,因为包含它们的目录仍然不在搜索路径。

我可以通过使用 Assembly.GetExecutingAssembly().Location 值通过 SetDllDirectory 设置本机 DLL 搜索路径来解决此问题,但这有两个主要缺点:

1) SetDllDirectory 更改全局 WinAPI 设置,并可能干扰同一 ASP.Net 工作进程中也使用本机代码 DLL 的其他代码;我还验证了使用 DllImport 属性不会与此设置混淆,因此现在更改它确实会破坏以前工作的东西。

2) 它仍然无法在 Visual Studio 中调试 ASP.Net 应用程序,因为 VS 将托管资源复制到一个临时目录中,但将本机 DLL 保留在项目构建目录中,因此它们最终位于不同的位置在调试会话中(并且每个调试会话都会擦除临时目录,因此手动将本机 DLL 复制到其中也不起作用;我必须将本机 DLL 复制到 IIS 的目录中以便调试会话找到它们,这显然是不可接受的解决方案)。

我真的很想在这里做兼容的事情,但到目前为止还没有找到这是什么,经过几天毫无结果的搜索,任何指针都将不胜感激。

【问题讨论】:

    标签: asp.net dllimport


    【解决方案1】:

    回答我自己的问题:

    1) 我在复制 Managed.DLL 时缺少的关键字是“影子复制”(James Schubert 比我见过的任何官方 Microsoft 文档都解释得更好),诀窍是改用 Assembly.CodeBase Assembly.Location,因为前者给出了 Managed.DLL 的原始位置,而后者给出了卷影副本的位置(John Sibly and Sneal 共享好的代码 sn-ps 从Assembly.CodeBase 中的 URI 中提取目录名称)。

    2) 使本机 DLL 的依赖关系可用的方法是在需要它们之前使用 LoadLibrary 显式加载它们(由于这会增加它们的引用计数,完成后也使用 FreeLibrary 释放它们)。

    所以,加载顺序是

    string dir = Assembly.GetExecutingAssembly().CodeBase;
    dir = new Uri(dir).LocalPath;
    dir = Path.GetDirectoryName(dir);
    IntPtr driver = LoadLibrary(dir + Path.DirectorySeparatorChar + "Driver.DLL");
    IntPtr managed = LoadLibrary(dir + Path.DirectorySeparatorChar + "Managed.DLL");
    

    以及卸货顺序

    FreeLibrary(managed);
    FreeLibrary(driver);
    

    (还要注意LoadLibraryFreeLibrary 调用的顺序)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-25
      • 1970-01-01
      • 2017-08-05
      • 2012-03-23
      • 1970-01-01
      • 1970-01-01
      • 2015-07-15
      相关资源
      最近更新 更多