Может ли проект C # AnyCPU включать dll для конкретной платформы - PullRequest
6 голосов
/ 18 января 2011

Наш продукт основан на множестве проектов C ++, но сейчас мы используем проекты C # для внешнего интерфейса. Мы также сейчас делаем 64-битную версию.
Наш план состоит в том, чтобы собрать все библиотеки C # под AnyCPU. Проекты C # будут иметь ссылки на библиотеки C ++ в общей папке bin. При сборке x64 папка bin будет содержать x64 версии наших библиотек c ++, а при сборке Win32 папка bin будет содержать 32-битные версии наших библиотек C ++. Таким образом, проекты C # будут собирать AnyCPU, но включая x64 или Win32 c ++ dll.
Мой вопрос, будет ли это работать? Во время выполнения все должно быть или все 32 или все 64 в зависимости от того, какой исполняемый файл мы запускаем, но может ли время компиляции обрабатывать проект, нацеленный на AnyCPU, который включает в себя специфическую для платформы dll? Или мы должны будем сделать платформо-зависимые версии всех наших библиотек C #? Спасибо

Ответы [ 4 ]

8 голосов
/ 18 января 2011

Это в первую очередь проблема развертывания, когда выбираются правильные библиотеки DLL для соответствующей операционной системы. Довольно просто, если вы создадите два проекта установки, один для x86, а другой для x64.

Также возможно сделать это прозрачным. Например, вы должны создать подкаталог x86 и x64 в каталоге, в котором находится ваш EXE-файл, и поместить соответственно 32-битную и 64-битную сборки DLL в эти подкаталоги. При запуске, проверьте IntPtr.Size, чтобы знать битность вашего процесса. Затем, соответственно, вызовите SetDllDirectory, чтобы Windows нашла правильную DLL. Как это:

using System.Runtime.InteropServices;
using System.Reflection;
using System.IO;
...
        public static void SetupDllDirectory() {
            string path = Assembly.GetEntryAssembly().Location;
            path = Path.Combine(path, IntPtr.Size == 8 ? "x64" : "x86");
            bool ok = SetDllDirectory(path);
            if (!ok) throw new System.ComponentModel.Win32Exception();
        }

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool SetDllDirectory(string path);

Используйте событие после сборки, чтобы скопировать библиотеки DLL. Использование Environment.SetEnvironmentVariable () для добавления каталога в переменную среды PATH - это еще один подход.

3 голосов
/ 18 января 2011

Насколько я помню, это работает.

У меня были только 32-битные DLL, скомпилированные c #, и он завис при запуске.Поэтому, если вы поместите туда 64-битные DLL, я думаю, вам не нужно перекомпилировать C #.

2 голосов
/ 18 января 2011

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

2 голосов
/ 18 января 2011

Я сделал это. Хотя это дает предупреждения компиляции.

...