У нас есть библиотека.NET, которая ссылается на один из наших неуправляемых dlls, позволяет, скажите:
К настоящему времени Unmanaged.dll является только 32-разрядным, таким образом, DotNet.dll отмечен с 32-разрядным типом ЦП.
64-разрядная поддержка должна быть добавлена. Как организовать dlls? Код IL DotNet.dll будет тем же и для 32-разрядных и для 64-разрядных версий.
В этом случае разработчик, пользующийся этими библиотеками, вынужден подать 2 заявки: 32-разрядный и 64-разрядный. Но в этом случае знание точно, что происходит.
Это совпадает с Опцией 1 кроме DotNet.dll, имеет тип ЦП AnyCPU.
Мне не нравится этот, потому что разработчик, пользующийся этими библиотеками, при перераспределении их приложения, не может сделать, хорошее задание подавания их заявки не отказывает, не устанавливая тип ЦП на их приложении:
Это делает Опцию 1 выше Опции 2.
DotNet.dll во времени выполнения определил бы, какая разрядность оно выполняется под, затем PInvoke корректный Unmanaged.dll.
Я бы выбрал вариант 3, скомпилировал управляемую сборку для AnyCPU и назвал неуправляемые сборки для их архитектуры. Я вижу две отдельные проблемы, которые влияют на это решение:
Я думаю, что разработчики .NET не ожидают, что им придется ссылаться на отдельный файл для каждой архитектуры. Я бы использовал AnyCPU, чтобы иметь ровно одну dll.
Если вы используете AnyCPU для управляемой сборки, будет ровно одна dll, так что это спорный вопрос.
Для неуправляемой сборки можно ожидать, что файлы, скомпилированные для разных архитектур, будут именоваться по-разному. С технической точки зрения, разные имена файлов позволяют помещать файлы для обеих архитектур в один и тот же каталог; это означает вызов другого файла во время выполнения в зависимости от архитектуры, но это не большая нагрузка. Я бы назвал файлы по-другому.
Вариант 3 кажется самым простым, а Вариант 1 - самым безопасным. Просто с точки зрения того, какую библиотеку вызывать, не похоже, что будет так сложно управлять ими, если вы не имеете дело с огромным количеством вызовов. Основная проблема заключается в том, что вам придется объявить любую заданную функцию дважды, используя разные имена для 32- и 64-битных версий, а затем просто изменить атрибут DllImport
, чтобы он указывал на правильную цель. Ваша функция-заглушка должна будет решить во время выполнения, какую из них вызывать.
Обратите внимание, что помимо логистики нет необходимости включать и в папку вашей библиотеки. Пока вы не вызываете вызов «неправильной» библиотеки, исключение этого не повлияет.
Я делаю следующее:
Я отправляю 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.