Компилировать для смешанной платформы (32, 64) и ссылаться на 32 или 64-битную DLL, разрешенную во время выполнения - PullRequest
5 голосов
/ 25 декабря 2010

Использование VS2010 под Windows 32 или 64 бит.Наше приложение C # вызывает стороннюю DLL (управляемую), которая взаимодействует с неуправляемой DLL.Сторонний API-интерфейс DLL выглядит идентичным в 32- или 64-разрядном режиме, хотя под ним находится ссылка на 32- или 64-разрядный неуправляемый DLL.

Мы хотим, чтобы наше приложение C # работало в 32- или 64-разрядной ОС, в идеале оно будет автоматическиОпределите ОС и загрузите соответствующую библиотеку DLL 32-й стороны - с помощью простого фабричного класса, который тестирует среду.Таким образом, самым подходящим решением будет папка времени выполнения, содержащая: OurApp.exe 3rdParty32.DLL 3rdPartyUnmanaged32.DLL 3rdParty64.DLL 3rdPartyUnmanaged64.DLL

Однако интерфейс для управляемых DLL-библиотек 3rdParty 32 и 64 идентичен, поэтому оба не могут бытьупоминается в том же проекте VS2010: при добавлении второго отображается предупреждающий треугольник, и на него нет ссылки.

Является ли мой единственный ответ на создание двух дополнительных библиотечных DLL-проектов для ссылок на 3-й части 32-й и 64-й библиотеки DLL?Таким образом, я бы закончил с этим расположением проекта: Проект 1: Создает OurApp.exe, динамически создает объект для проекта2 или проекта3.Проект 2: Сборка OurApp32.DLL, которая ссылается на 3rdParty32.dll Проект 3: Сборка OurApp64.DLL, которая ссылается на 3rdParty64.dll

Ответы [ 4 ]

5 голосов
/ 25 декабря 2010

Поскольку у вас есть неуправляемый код, который является 32-битным или 64-битным, вы теряете преимущество того, что управляемый код может переходить в любой режим во время выполнения.Проще всего настроить файл make для сборки приложения дважды, один раз для 64-битной и один раз для 32-битной, и использовать условные разделы в файле csproj для ссылки на 32-битные или 64-битные неуправляемые библиотеки DLL.Разрешите установщику установить двоичные файлы, соответствующие платформе, найденной во время установки.

0 голосов
/ 25 декабря 2010

Вот идея, которая должна быть реализована путем настройки процесса сборки:

Сделайте так, чтобы ваш проект дважды компилировался в YourApp32.exe и YourApp64.exe, изменяя ссылки соответствующим образом.Затем также создайте третий проект с загрузчиком YourApp.exe, который будет проверять только разрядность системы и загружать либо YourApp32.exe, либо YourApp64.exe.

Естественно, это, вероятно, следует делать толькоВыпускать сборки, потому что вы эффективно удваиваете время компиляции, что будет раздражать разработчиков.

0 голосов
/ 25 декабря 2010

Одним из вариантов будет использование отражения на вашей фабрике для загрузки исправленной сторонней сборки во время выполнения, создания экземпляра соответствующего класса и возврата ссылки на него. Затем вы можете просто поместить сборки в тот же каталог, что и ваш исполняемый файл, и загрузить нужную во время выполнения, не добавляя ссылку на проект. Однако обычно для этого используется либо известный базовый абстрактный класс, либо интерфейс из другой сборки (обычно такой, который предназначен только для хранения необходимых объявлений). Не похоже, что у вас есть это.

Тем не менее, в зависимости от сложности иерархии типов управляемой DLL стороннего производителя, на этом маршруте может быть вариант с немного большей работой.

  1. Создайте набор классов в вашем собственном проекте, который отражает структуру сторонней библиотеки dll. Предполагая, что сторонняя библиотека не слишком сложна, вероятно, это будет всего лишь один класс со многими методами. Вам также придется воссоздавать любые структуры, переданные туда-сюда, если таковые имеются.
  2. Создайте набор делегатов, которые соответствуют сигнатурам методов, вызываемых в dll. Например, такой метод, как: string DoFoo(int a, int b) будет иметь делегат что-то вроде delegate string DoFooDelegate(int a, int b). Если методы имеют одинаковую сигнатуру, вы можете использовать один делегат для всех них. Добавьте к вашему набору классов, созданных перед переменной, для каждого метода, вызываемого в сторонней DLL. Таким образом, ваши классы будут иметь набор членов в соответствии с private DoFooDelegate doFoo;. Тогда может быть любой уровень доступа, который вы считаете подходящим.
  3. Для наиболее утомительной части (хотя вы, вероятно, могли бы сделать большую часть этого с помощью общих функций, чтобы помочь). Используя этот http://msdn.microsoft.com/en-us/library/ms228976.aspx и этот http://msdn.microsoft.com/en-us/library/74x8f551.aspx в качестве руководства, создайте экземпляр классов-оболочек, подключите каждый метод из сторонней библиотеки к соответствующему члену в ваших классах. Это должно быть сделано на вашем заводе. После этого верните новый экземпляр. После этого вы сможете вызывать сторонние сборки через классы-оболочки.

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

0 голосов
/ 25 декабря 2010

Не могу сказать, что делал это раньше, но быстрый поиск подсказывает, что вы можете программировать на интерфейсе и динамически загружать библиотеку с помощью рефлексии.

Рассматривали ли вы это?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...