Что лучший способ состоит в том, чтобы поддерживать несколько архитектуры в смешанной управляемой/неуправляемой среде?

Фон

У нас есть библиотека.NET, которая ссылается на один из наших неуправляемых dlls, позволяет, скажите:

  • DotNet.dll
  • Unmanaged.dll

К настоящему времени Unmanaged.dll является только 32-разрядным, таким образом, DotNet.dll отмечен с 32-разрядным типом ЦП.

64-разрядная поддержка должна быть добавлена. Как организовать dlls? Код IL DotNet.dll будет тем же и для 32-разрядных и для 64-разрядных версий.

Опция 1

  • Папка библиотек на 32 бита
    • DotNet.dll, тип ЦП 32-разрядных
    • Unmanaged.dll, скомпилированный как 32-разрядный
  • Папка библиотек на 64 бита
    • DotNet.dll, тип ЦП 64-разрядных
    • Unamanged.dll, скомпилированный как 64-разрядный

В этом случае разработчик, пользующийся этими библиотеками, вынужден подать 2 заявки: 32-разрядный и 64-разрядный. Но в этом случае знание точно, что происходит.

Опция 2

Это совпадает с Опцией 1 кроме DotNet.dll, имеет тип ЦП AnyCPU.

  • Папка библиотек на 32 бита
    • DotNet.dll, тип ЦП AnyCPU
    • Unmanaged.dll, скомпилированный как 32-разрядный
  • Папка библиотек на 64 бита
    • DotNet.dll, тип ЦП AnyCPU
    • Unamanged.dll, скомпилированный как 64-разрядный

Мне не нравится этот, потому что разработчик, пользующийся этими библиотеками, при перераспределении их приложения, не может сделать, хорошее задание подавания их заявки не отказывает, не устанавливая тип ЦП на их приложении:

  • Если они будут использовать Папку Библиотек на 32 бита, то на 64-разрядной ОС откажет их процесс
  • Если они будут использовать Папку Библиотек на 64 бита, то на 32-разрядной ОС откажет их процесс

Это делает Опцию 1 выше Опции 2.

Опция 3

  • Unmanaged_x32.dll, скомпилированный как 32-разрядный
  • Unmanaged_x64.dll, скомпилированный как 64-разрядный
  • DotNet.dll, тип ЦП AnyCPU

DotNet.dll во времени выполнения определил бы, какая разрядность оно выполняется под, затем PInvoke корректный Unmanaged.dll.

Вопрос (вопросы)

  1. Как разработчик этих библиотек, какая опция имеет большую часть смысла?
  2. Как разработчик, пользующийся библиотекой DotNet.dll, какая опция имеет большую часть смысла?
    1. Для Опции 3 при использовании DotNet.dll Вы хотели бы знать, что библиотека во времени выполнения определяет что Unmanaged.dll использовать?
    2. Что относительно перераспределения Вашего приложения с этими библиотеками?
  3. Некоторая опция отсутствует?
7
задан earlNameless 26 July 2010 в 17:24
поделиться

3 ответа

Я бы выбрал вариант 3, скомпилировал управляемую сборку для AnyCPU и назвал неуправляемые сборки для их архитектуры. Я вижу две отдельные проблемы, которые влияют на это решение:

Следует ли компилировать управляемую сборку для AnyCPU или для конкретной архитектуры?

Я думаю, что разработчики .NET не ожидают, что им придется ссылаться на отдельный файл для каждой архитектуры. Я бы использовал AnyCPU, чтобы иметь ровно одну dll.

Должны ли библиотеки называться явно в соответствии с их архитектурой?

Если вы используете AnyCPU для управляемой сборки, будет ровно одна dll, так что это спорный вопрос.

Для неуправляемой сборки можно ожидать, что файлы, скомпилированные для разных архитектур, будут именоваться по-разному. С технической точки зрения, разные имена файлов позволяют помещать файлы для обеих архитектур в один и тот же каталог; это означает вызов другого файла во время выполнения в зависимости от архитектуры, но это не большая нагрузка. Я бы назвал файлы по-другому.

4
ответ дан 7 December 2019 в 05:16
поделиться

Вариант 3 кажется самым простым, а Вариант 1 - самым безопасным. Просто с точки зрения того, какую библиотеку вызывать, не похоже, что будет так сложно управлять ими, если вы не имеете дело с огромным количеством вызовов. Основная проблема заключается в том, что вам придется объявить любую заданную функцию дважды, используя разные имена для 32- и 64-битных версий, а затем просто изменить атрибут DllImport , чтобы он указывал на правильную цель. Ваша функция-заглушка должна будет решить во время выполнения, какую из них вызывать.

Обратите внимание, что помимо логистики нет необходимости включать и в папку вашей библиотеки. Пока вы не вызываете вызов «неправильной» библиотеки, исключение этого не повлияет.

2
ответ дан 7 December 2019 в 05:16
поделиться

Я делаю следующее:

Я отправляю DotNet.dll, скомпилированную для AnyCPU с переносимыми директивами P / Invoke (как и должны быть декларации API).

Я отправляю unmanaged_32.bin и unmanaged_64.bin и устанавливаю только правильный для архитектуры unmanaged.dll во время установки.

Уловка, которая все еще работает, - это установить unmanaged.dll следующим образом:

x86: C: \ Program Files (x86) \ Common Files \ unmanaged.dll x64: C: \ Program Files \ Common Files \ unmanaged.dll

Если C: \ Program Files \ Common Files находится в системном пути, это заставит P / Invoke автоматически захватить правильную DLL.

2
ответ дан 7 December 2019 в 05:16
поделиться
Другие вопросы по тегам:

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