Архитектура ЦП Независимый P/Invoke: DllName или путь могут быть “динамичными”?

Инструмент NDepend заключается в кавычки как [1 123] Инструменты Метрики качества , но это в значительной степени также обнаружение Нарушения регулярной кодовой последовательности инструмент. Правовая оговорка: Я - один из разработчиков инструмента

С NDepend, можно записать Правило Кода по Запросам LINQ (что мы называем CQLinq) . [Больше чем 112] 200 правил кода CQLinq предложены по умолчанию. Сила CQLinq состоит в том, что это просто, чтобы записать правило кода и добраться сразу результаты. Средства предложены для просмотра подобранных элементов кода. Например:

CQLinq code rule

, Около которого, NDepend идет со многими другими статический анализ как [1 112] функции. Они включают:

10
задан Cheetah 15 October 2009 в 17:01
поделиться

2 ответа

Невозможно использовать одну подпись PInvoke и получить желаемое поведение. Атрибут записывается в метаданные и должен иметь постоянные значения. Один из способов взлома - использовать несколько методов.

public static class NativeMethods32 {
  [DllImport("Foo.dll")]
  public static extern int SomeMethod();
}

public static class NativeMethods64 {
  [DllImport("Foo_x864.dll")]
  public static extern int SomeMethod();
}

public static class NativeMethods {
  public static bool Is32Bit { return 4 == IntPtr.Size; }
  public static SomeMethod() {
    return Is32Bit ? 
      NativeMethods32.SomeMethod(); 
      NativeMethods64.SomeMethod();
  }
}

Однако это не лучший подход. Более простой подход - сделать так, чтобы DLL имела одно и то же имя на нескольких платформах и создала сигнатуру PInvoke, не зависящую от платформы. Это подход, который используют большинство / все библиотеки Windows.

4
ответ дан 3 December 2019 в 22:00
поделиться

«Если бы вместо разных имен DLL было одно и то же имя в разных папках, открываются ли при этом какие-либо другие параметры?»

Возможно, это сработает для вас:

public static class NativeMethods
{
  // here we just use "Foo" and at runtime we load "Foo.dll" dynamically
  // from any path on disk depending on the logic you want to implement
  [DllImport("Foo", EntryPoint = "bar")]
  private void bar();

  [DllImport("kernel32")]
  private unsafe static extern void* LoadLibrary(string dllname);

  [DllImport("kernel32")]
  private unsafe static extern void FreeLibrary(void* handle);

  private sealed unsafe class LibraryUnloader
  {
    internal LibraryUnloader(void* handle)
    {
      this.handle = handle;
    }

    ~LibraryUnloader()
    {
      if (handle != null)
        FreeLibrary(handle);
    }

    private void* handle;

  } // LibraryUnloader

  private static readonly LibraryUnloader unloader;

  static NativeMethods()
  {
    string path;

    if (IntPtr.Size == 4)
      path = "path/to/the/32/bit/Foo.dll";
    else
      path = "path/to/the/64/bit/Foo.dll";

    unsafe
    {
      void* handle = LoadLibrary(path);

      if (handle == null)
        throw new DllNotFoundException("unable to find the native Foo library: " + path);

      unloader = new LibraryUnloader(handle);
    }
  }
}

Он состоит в явная загрузка собственной библиотеки с полным путем до того, как P / Invoke попытается ее загрузить.

Что вы думаете?

11
ответ дан 3 December 2019 в 22:00
поделиться
Другие вопросы по тегам:

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