以编程方式更改要导入的非托管DLL的位置

时间:2012-09-10 19:32:53

标签: c# pinvoke unmanaged dllimport

  

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

我在我的C#托管代码中使用非托管代码。我有非托管DLL嵌入在应用程序的可执行文件中。为了完成这项工作,我在对DLLs方法进行任何调用之前将资源/ 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的位置?直到运行时我才知道。

1 个答案:

答案 0 :(得分:4)

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

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