嵌入非托管的DLL到一个托管的C#DLL [英] Embedding unmanaged dll into a managed C# dll

查看:386
本文介绍了嵌入非托管的DLL到一个托管的C#DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用使用dllimport的非托管C ++ DLL一个托管的C#DLL。所有的是伟大的工作。
不过,我想嵌入非托管的DLL我管理的DLL内由微软有解释:

I have a managed C# dll that uses an unmanaged C++ dll using DLLImport. All is working great. However, I want to embed that unmanaged DLL inside my managed DLL as explain by Microsoft there:

<一个href=\"http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.dllimportattribute.aspx\">http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.dllimportattribute.aspx

所以我添加的非托管的dll文件来管理我的dll项目,将该属性设置为嵌入的资源,并修改为dllimport喜欢的东西。

So I added the unmanaged dll file to my managed dll project, set the property to 'Embedded Resource' and modify the DLLImport to something like

函数[DllImport(非托管Driver.dll,包装机,版本= 1.0.0.0,文化=中立,公钥=空,CallingConvention = CallingConvention.Winapi)]

[DllImport("Unmanaged Driver.dll, Wrapper Engine, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null", CallingConvention = CallingConvention.Winapi)]

在哪里
'包装发动机'是我托管DLL的程序集名称
非托管Driver.dll就是非托管的DLL

where 'Wrapper Engine' is the assembly name of my managed DLL 'Unmanaged Driver.dll' is the unmanaged DLL

当我跑,我得到:
访问被拒绝。 (从HRESULT异常:0X80070005(E_ACCESSDENIED))

When I run, I get: Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))

我从MSDN和 http://blogs.msdn.com/suzcook/看到这应该是可能的。 ..

I saw from MSDN and from http://blogs.msdn.com/suzcook/ that's supposed to be possible...

推荐答案

您可以嵌入非托管DLL作为一种资源,如果你在初始化过程中它自己解压到一个临时目录,并使用P / Invoke之前调用LoadLibrary显式地加载它。我已经使用这种技术,它工作得很好。你可以preFER只是将其链接到组装的迈克尔指出一个单独的文件,但有它全部在一个文件中都有其优点。下面是我使用的方法:

You can embed the unmanaged DLL as a resource if you extract it yourself to a temporary directory during initialization, and load it explicitly with LoadLibrary before using P/Invoke. I have used this technique and it works well. You may prefer to just link it to the assembly as a separate file as Michael noted, but having it all in one file has its advantages. Here's the approach I used:

// Get a temporary directory in which we can store the unmanaged DLL, with
// this assembly's version number in the path in order to avoid version
// conflicts in case two applications are running at once with different versions
string dirName = Path.Combine(Path.GetTempPath(), "MyAssembly." +
  Assembly.GetExecutingAssembly().GetName().Version.ToString());
if (!Directory.Exists(dirName))
  Directory.CreateDirectory(dirName);
string dllPath = Path.Combine(dirName, "MyAssembly.Unmanaged.dll");

// Get the embedded resource stream that holds the Internal DLL in this assembly.
// The name looks funny because it must be the default namespace of this project
// (MyAssembly.) plus the name of the Properties subdirectory where the
// embedded resource resides (Properties.) plus the name of the file.
using (Stream stm = Assembly.GetExecutingAssembly().GetManifestResourceStream(
  "MyAssembly.Properties.MyAssembly.Unmanaged.dll"))
{
  // Copy the assembly to the temporary file
  try
  {
    using (Stream outFile = File.Create(dllPath))
    {
      const int sz = 4096;
      byte[] buf = new byte[sz];
      while (true)
      {
        int nRead = stm.Read(buf, 0, sz);
        if (nRead < 1)
          break;
        outFile.Write(buf, 0, nRead);
      }
    }
  }
  catch
  {
    // This may happen if another process has already created and loaded the file.
    // Since the directory includes the version number of this assembly we can
    // assume that it's the same bits, so we just ignore the excecption here and
    // load the DLL.
  }
}

// We must explicitly load the DLL here because the temporary directory 
// is not in the PATH.
// Once it is loaded, the DllImport directives that use the DLL will use
// the one that is already loaded into the process.
IntPtr h = LoadLibrary(dllPath);
Debug.Assert(h != IntPtr.Zero, "Unable to load library " + dllPath);

这篇关于嵌入非托管的DLL到一个托管的C#DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆