Ну, есть хитрый способ сделать это, но он добавляет дополнительную нагрузку на код (хотя вы могли бы просто сделать это в начале вашего приложения).
Он основан на создании нового домена приложения с путями приватных бинов для конкретной платформы, откуда загружать сборки. Затем вы прячете свой собственный код в 32- или 64-битные каталоги, и он загружает то, что когда-либо будет наиболее подходящим.
Итак, ради аргумента у вас есть проект C ++ CLR с:
#pragma once
using namespace System;
namespace NativeLib {
public ref class NativeClass
{
public:
static void DoSomething()
{
Console::WriteLine("IntPtr.Size = {0}", IntPtr::Size);
}
};
}
Создайте как 32, так и 64 бит. Ссылка на приложение C # для использования библиотеки.
Теперь вам нужно изменить код, чтобы он создавал новый домен приложения, и запускать весь ваш код в нем (вы также можете создавать типы по умолчанию, но это делает его немного более сложным и потенциально медленным).
Итак, определите класс начальной загрузки для запуска приложения:
using NativeLib;
namespace BitnessTest
{
class StartClass
{
public static void Start()
{
NativeClass.DoSomething();
}
}
}
Наконец, измените вашу функцию Main на что-то вроде:
using System;
using System.Reflection;
namespace BitnessTest
{
class Program
{
static void Main(string[] args)
{
AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
if (IntPtr.Size > 4)
{
setup.PrivateBinPath = "x64";
}
else
{
setup.PrivateBinPath = "x86";
}
AppDomain appDomain = AppDomain.CreateDomain("Real Domain", null, setup);
appDomain.DoCallBack(StartClass.Start);
}
}
}
Теперь убедитесь, что вы удалили NativeLib.dll из текущего каталога приложения, создали каталог x86 и x64 и поместили соответствующие версии собственного lib в каждый из них. Запустите его, и теперь он должен работать на 32 и 64 бит.
Если вам не нужен другой домен приложения и вы хотите жить с устаревшим кодом (который может уйти, но все еще находится в .net 4), вы можете сделать:
if (IntPtr.Size > 4)
{
AppDomain.CurrentDomain.AppendPrivatePath("x64");
}
else
{
AppDomain.CurrentDomain.AppendPrivatePath("x86");
}
StartClass.Start();
Конечно, есть предостережения, они основаны на том факте, что сборки обычно имеют позднюю привязку, поэтому, если перед созданием домена приложения вы используете нативные типы, он, вероятно, сломается. Есть также способы сделать это более универсальным, например, вы можете написать исполняемый файл-обертку, который загружает сборку с задержкой загрузки, содержащую ваш реальный код, что означает, что он будет работать более обобщенно.
Конечно, если вы хотите, чтобы это была библиотека, вам, возможно, придется пойти со сборкой обвязки загрузки, путаницей с закрытым путем приложения, скажем, статическим конструктором, что может быть не очень вежливым делом;)