Используя 32 бита или 64 бита dll в C# DllImport

Вот ситуация, я использую C базирующийся dll в моем приложении dot.net. Существует 2 dlls, каждый - 32 бита под названием MyDll32.dll, и другой версия на 64 бита под названием MyDll64.dll.

Существует статическая переменная, содержащая имя файла DLL: строка DLL_FILE_NAME.

и это используется следующим образом:

[DllImport(DLL_FILE_NAME, CallingConvention=CallingConvention.Cdecl, EntryPoint=Func1")]
private static extern int is_Func1(int var1, int var2);

Простой до сих пор.

Как можно предположить, программное обеспечение компилируется с "Любым ЦП", включенным.

У меня также есть следующий код, чтобы определить, должна ли система использовать файл на 64 бита или файл на 32 бита.

#if WIN64
        public const string DLL_FILE_NAME = "MyDll64.dll";
#else
        public const string DLL_FILE_NAME = "MyDll32.dll";        
#endif

К настоящему времени необходимо видеть проблему.. DLL_FILE_NAME определяется во время компиляции а не во время выполнения, таким образом, право dll не загружается согласно контексту выполнения.

Каков был бы корректный способ заниматься этой проблемой? Я не хочу два файла выполнения (один для 32 битов и другой для 64 битов)? Как я могу установить DLL_FILE_NAME, прежде чем он будет использоваться в операторе DllImport?

59
задан 3 June 2012 в 15:02

1 ответ

Прием я использую для [1 128] V8. Сеть является этим:

  1. Создают новый C# "интерфейсный" проект прокси со всем определением для переключения между различной архитектурой. В моем случае проект назвали V8.Net-ProxyInterface; пример:
 public unsafe static class V8NetProxy
    {
    #if x86
            [DllImport("V8_Net_Proxy_x86")]
    #elif x64
            [DllImport("V8_Net_Proxy_x64")]
    #else
            [DllImport("V8_Net_Proxy")] // (dummy - NOT USED!)
    #endif
            public static extern NativeV8EngineProxy* CreateV8EngineProxy(bool enableDebugging, void* debugMessageDispatcher, int debugPort);

ЭТО - проект, на который Вы сошлетесь. НЕ ссылайтесь на следующие два:

  1. Создают еще два проекта генерировать x64 и x86 версии библиотеки. Это ОЧЕНЬ ЛЕГКО: Просто copy-n-paste для дублирования .csproj файл в той же папке и переименовал их. В моем случае файл проекта был переименован к V8.Net-ProxyInterface-x64 и V8.Net-ProxyInterface-x86, затем я добавил проекты к своему решению. Откройте настройки проекта для каждого из них в Visual Studio и удостоверьтесь эти Assembly Name, имеет или x64 или x86 на имя. В этой точке у Вас есть 3 проекта: первый проект "заполнителя" и 2 архитектурно-зависимых. Для 2 новых проектов:

    a) Открывают интерфейс x64 настройки проекта, перейдите в Build вкладка, выберите All Platforms для [1 110] наверху, затем войдите x64 в [1 112].

    b) Открывают интерфейс x86 настройки проекта, перейдите в Build вкладка, выберите All Platforms для [1 115] наверху, затем войдите x86 в [1 117].

  2. Открывают Build->Configuration Manager... и удостоверяются, что x64 выбран, как платформа для x64 проектов, и x86 выбрана для x86 проектов, и для [1 121] И ДЛЯ Release конфигурации.

  3. Удостоверяются 2 новых интерфейсных проекта (для x64 и x86) вывод к тому же местоположению Вашего проекта хоста (см. установку Build->Output path проекта).

  4. заключительное волшебство: В статическом конструкторе для моего механизма я быстро подключаю к сопоставителю блока:

static V8Engine()
{
    AppDomain.CurrentDomain.AssemblyResolve += Resolver;
}

В Resolver метод, я просто загружаю файл на основе текущей платформы, обозначенной текущим процессом (примечание: этот код является упрощенной версией и не протестированный):

var currentExecPath = Assembly.GetExecutingAssembly().Location;
var platform = Environment.Is64BitProcess ? "x64" : "x86";
var filename = "V8.Net.Proxy.Interface." + platform + ".dll"
return Assembly.LoadFrom(Path.Combine(currentExecPath , fileName));

Наконец, перейдите к своему проекту хоста в проводнике решения, разверните References, выберите первый фиктивный проект, который Вы создали на шаге 1, щелкните правой кнопкой по нему, чтобы открыть свойства и установить Copy Local на [1 127]. Это позволяет Вам разрабатывать с ОДНИМ названием каждой функции P/Invoke при использовании сопоставителя для выяснения который на самом деле загрузиться.

Примечание, которое загрузчик сборок только выполняет при необходимости. Это только инициировано (в моем случае) автоматически системой CLR на первый доступ к классу механизма. То, как это переводит в Вас, зависит от того, как Ваш проект хоста разработан.

0
ответ дан 1 November 2019 в 11:47

Другие вопросы по тегам:

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