为了账号安全,请及时绑定邮箱和手机立即绑定

将非托管dll嵌入到托管C#dll中

将非托管dll嵌入到托管C#dll中

C#
PIPIONE 2019-08-30 16:44:53
我有一个使用DLLImport使用非托管C ++ DLL的托管C#dll。一切都很好。但是,我想在我的托管DLL中嵌入非托管DLL,如Microsoft解释:http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.dllimportattribute.aspx所以我将非托管dll文件添加到我的托管dll项目,将属性设置为'Embedded Resource'并将DLLImport修改为:[DllImport("Unmanaged Driver.dll, Wrapper Engine, Version=1.0.0.0,Culture=neutral, PublicKeyToken=null",CallingConvention = CallingConvention.Winapi)]其中'Wrapper Engine'是我托管DLL的程序集名称'Unmanaged Driver.dll'是非托管DLL当我跑步时,我得到:访问被拒绝。(HRESULT异常:0x80070005(E_ACCESSDENIED))我从MSDN和http://blogs.msdn.com/suzcook/看到了这应该是可能的......
查看完整描述

3 回答

?
九州编程

TA贡献1785条经验 获得超4个赞

如果在初始化期间将其自身提取到临时目录,则可以将非托管DLL作为资源嵌入,并在使用P / Invoke之前使用LoadLibrary显式加载它。我使用过这种技术,效果很好。您可能更喜欢将它作为单独的文件链接到程序集,正如迈克尔所指出的那样,但将它全部放在一个文件中有其优点。这是我使用的方法:


// 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);


查看完整回答
反对 回复 2019-08-30
  • 3 回答
  • 0 关注
  • 1050 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信