Встраивание неуправляемого dll в управляемый C# dll

Вы можете настроить адресатов так же, как в Neo. Кроме того, вы можете использовать SAP Live Link 365 для электронной почты, как в ссылке

82
задан DimaSan 27 October 2016 в 07:30
поделиться

2 ответа

Я не знал, что это возможно - я предположил бы, что CLR должен извлечь встроенный собственный DLL где-нибудь (Windows должен иметь файл для DLL для загрузки его - он не может загрузить изображение из необработанной памяти), и везде, где он пытается сделать это, процесс не имеет разрешения.

Что-то как Монитор Процесса от SysInternals мог бы дать Вам ключ к разгадке, если pronblem - то, что создание файла DLL перестало работать...

Обновление:

<час>

А-ч... теперь, когда я был в состоянии прочитать статью Suzanne Cook (страница не представала передо мной прежде), обратите внимание, что она не говорит о встраивании собственного DLL как ресурс в управляемом DLL, а скорее как связанный ресурс - собственный DLL все еще должен быть своим собственным файлом в файловой системе.

Видят http://msdn.microsoft.com/en-us/library/xawyf94k.aspx , где это говорит:

файл ресурсов не добавляется к выходному файлу. Это отличается от / опции ресурса, которая действительно встраивает файл ресурсов в выходной файл.

то, Что это, кажется, делает, добавляют метаданные к блоку, который заставляет собственный DLL логически быть частью блока (даже при том, что это - физически отдельный файл). Таким образом, вещи как помещение управляемой сборки в GAC будут автоматически включать собственный DLL, и т.д.

8
ответ дан Michael Burr 24 November 2019 в 09:20
поделиться

Вы можете встроить неуправляемую DLL в качестве ресурса, если вы самостоятельно извлечете ее во временный каталог во время инициализации и загрузите его явно с LoadLibrary перед использованием P / Invoke. Я использовал эту технику, и она хорошо работает. Вы можете предпочесть просто связать его со сборкой в ​​виде отдельного файла, как отметил Майкл, но наличие всего этого в одном файле имеет свои преимущества. Вот подход, который я использовал:

// 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);
61
ответ дан 24 November 2019 в 09:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: