【问题标题】:Programmatically change the location of an unmanaged DLL to import [duplicate]以编程方式更改要导入的非托管 DLL 的位置 [重复]
【发布时间】:2012-09-11 04:04:43
【问题描述】:

可能重复:
How to separate managed and unmanaged DLLs in another directory

我将非托管代码与我的 C# 托管代码一起使用。我在应用程序的可执行文件中嵌入了非托管 DLL。为了完成这项工作,我在调用 DLL 方法之前将资源/DLL 提取到一个文件中。

public static class ResourceExtractor
{
    public static void ExtractResourceToFile(string resourceName, string filename)
    {
        if (!System.IO.File.Exists(filename))
            using (System.IO.Stream s = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
            using (System.IO.FileStream fs = new System.IO.FileStream(filename, System.IO.FileMode.Create))
            {
                byte[] b = new byte[s.Length];
                s.Read(b, 0, b.Length);
                fs.Write(b, 0, b.Length);
            }
    }
}

因此,在调用 DLL 之前,我确保执行以下操作:

ResourceExtractor.ExtractResourceToFile("Namespace.dll_name.dll", "dll_name.dll");

并包装我拥有的非托管 DLL 的方法...

public class DLLWrapper
{
    public const string dllPath = "dll_name.dll";

    [DllImport(dllPath)]
    public static extern uint functionA();

    [DllImport(dllPath)]
    public static extern uint functionB();

    [DllImport(dllPath)]
    public static extern uint functionC();
}

现在问题来了……

这一切都有效。我喜欢的是它创建了位于可执行文件旁边的 DLL。我宁愿在一个临时目录中创建 DLL 并从那里加载它。比如……

string tempDLLname = Path.GetTempFileName();
ResourceExtractor.ExtractResourceToFile("Namespace.dll_name.dll", tempDLLname );
DLLWrapper.dllPath = tempDLLname;

...

public class DLLWrapper
{
    public static string dllPath;

    [DllImport(dllPath)]
    public static extern uint functionA();

    [DllImport(dllPath)]
    public static extern uint functionB();

    [DllImport(dllPath)]
    public static extern uint functionC();
}

但这不起作用,因为[DllImport(path)] 要求路径是const。那么如何更改要从中加载 DLL 的位置呢?直到运行时我才知道。

【问题讨论】:

    标签: c# pinvoke unmanaged dllimport


    【解决方案1】:

    在对 dll 调用任何调用之前,您可以显式使用 LoadLibrary 并传入您将其提取到的完整路径。

    http://msdn.microsoft.com/en-us/library/windows/desktop/ms684175(v=vs.85).aspx

    【讨论】:

    • 你能扩展这个答案吗?我查看了您的链接,但我不清楚如何实际实施。
    • 在将 dll 提取到临时位置后,立即使用该完整路径调用 LoadLibrary 以将其加载到进程内存中。只要 dll name 与您在 DllImport 中使用的匹配,对导出函数的后续调用将由加载的 dll 处理。同一个 dll 名称不能为同一个进程在内存中加载两次。
    • 像魅力一样工作。非常感谢。
    猜你喜欢
    • 2019-02-07
    • 2013-03-20
    • 2011-03-06
    • 2019-07-16
    • 1970-01-01
    • 2012-01-12
    • 2010-10-14
    相关资源
    最近更新 更多