猿问

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

我有一个使用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/看到了这应该是可能的......


PIPIONE
浏览 1051回答 3
3回答

九州编程

如果在初始化期间将其自身提取到临时目录,则可以将非托管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 versionsstring dirName = Path.Combine(Path.GetTempPath(), "MyAssembly." +&nbsp; Assembly.GetExecutingAssembly().GetName().Version.ToString());if (!Directory.Exists(dirName))&nbsp; 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(&nbsp; "MyAssembly.Properties.MyAssembly.Unmanaged.dll")){&nbsp; // Copy the assembly to the temporary file&nbsp; try&nbsp; {&nbsp; &nbsp; using (Stream outFile = File.Create(dllPath))&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; const int sz = 4096;&nbsp; &nbsp; &nbsp; byte[] buf = new byte[sz];&nbsp; &nbsp; &nbsp; while (true)&nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; int nRead = stm.Read(buf, 0, sz);&nbsp; &nbsp; &nbsp; &nbsp; if (nRead < 1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; outFile.Write(buf, 0, nRead);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }&nbsp; catch&nbsp; {&nbsp; &nbsp; // This may happen if another process has already created and loaded the file.&nbsp; &nbsp; // Since the directory includes the version number of this assembly we can&nbsp; &nbsp; // assume that it's the same bits, so we just ignore the excecption here and&nbsp; &nbsp; // load the DLL.&nbsp; }}// We must explicitly load the DLL here because the temporary directory&nbsp;// 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);
随时随地看视频慕课网APP
我要回答