Способы доступа к 32-битной DLL из 64-битного exe - программирование
Подтвердить что ты не робот

Способы доступа к 32-битной DLL из 64-битного exe

У меня есть проект, который должен быть скомпилирован и запущен в режиме 64 бит. К сожалению, мне необходимо вызвать DLL, доступную только в 32-битном режиме, поэтому я не могу разместить все в одном проекте Visual Studio. Я работаю над тем, чтобы найти лучший способ обернуть 32-битную DLL в свой собственный exe/service и выпустить удаленный (хотя и на тот же компьютер) вызов этого exe/service из моего 64-битного приложения. Моя ОС - 64-разрядная версия Win7 Pro.

Необходимые вызовы для этого 32-битного процесса - несколько десятков в секунду, но низкий объем данных. Это приложение для анализа изображений в реальном времени, поэтому время отклика является критическим, несмотря на низкий уровень громкости. Множество отправных/принимающих одиночных примитивов.

В идеале я бы разместил службу WCF для размещения этой DLL, но в 64-битной ОС нельзя заставить службу работать как x86! Источник. Это очень неудачно, так как я назначил функции вызовам службы WCF только на 4 мс на моей машине.

Я экспериментировал с именованными каналами .net. Я нашел их в 40-50 раз медленнее, чем WCF (непригодным для меня).

Любые другие варианты или предложения для наилучшего способа приблизиться к моей загадке?

4b9b3361

Ответ 1

Как вы правильно заметили, нет способа смешать битту в том же процессе. Вам потребуется отдельный процесс для вашей 32-битной части.

Я думаю, что хостинг WCF-сервиса - это правильный путь. Ваша ссылка говорит только о wcfsvchost. Я уверен, что вы можете создать свою собственную службу Windows и разместить службу WCF на 32-разрядной версии.

Смотрите эту ссылку: Как разместить службу WCF в управляемом приложении. Вы можете разместить свою службу в любом управляемом приложении, в том числе в службе Windows, и запускать его под нужную вам битту.

Это количество кода, необходимого для самостоятельной установки службы WCF в вашем приложении, при условии, что вы только что создали новую службу под названием MyService, и соответствующая конфигурация была добавлена ​​в app.config:

class Program
{
    static void Main(string[] args)
    {
        using(ServiceHost host = new ServiceHost(typeof(MyService), new Uri[0]))
        {
            host.Open();
            Console.ReadKey();    
        }
    }
}

Вышеупомянутая программа будет работать точно также, также если вы ее скомпилируете явно 32 или 64 бит.

Ответ 2

Отсутствует. Точка. 32-разрядная dll в 64-битном процессе = нет.

То, что я делаю, это запустить 32-битный процесс-обертку и обмениваться с ним с помощью WCF - как и вы. Я могу заставить ОС работать 32 бит.

У меня есть основная библиотека (Tradex.Connectivity.Core), с независимым от платформы .NET-кодом. У меня есть две оболочки (Wrapper32.exe, Wapper64.exe), которые запускают и загружают независимый код, а затем загружают класс (управляемый С++). Работает как шарм.

Это для меня единственный способ - вы не можете загружать 32 и 64-разрядные элементы.

Ответ 3

Я знаю, что этот ответ может быть немного запоздалым, но некоторое время назад я столкнулся с такой же проблемой (загрузка 32-разрядной DLL в сборку AnyCPU на 64-битной машине).

В качестве решения я написал LegacyWrapper. Он в основном состоит из 32-разрядной обертки exe, загружающей желаемую DLL, обмениваясь информацией с вашим приложением через именованные каналы.

Вызов будет выглядеть так:

// Define delegate matching api function
private delegate int GetSystemMetrics(int index);

// Create new WrapperClient
// Remember to ensure a call to the Dispose()-Method!
using (var client = new WrapperClient())
{
    // Make calls providing library name, function name, and parameters
    int x = (int)client.Invoke<GetSystemMetrics>("User32.dll", "GetSystemMetrics", new object[] { 0 });
    int y = (int)client.Invoke<GetSystemMetrics>("User32.dll", "GetSystemMetrics", new object[] { 1 });
}

Для некоторых деталей вы можете обратиться к этому сообщению .

Изменить: Начиная с версии 2.1, LegacyWrapper также поддерживает загрузку 64-битных DLL из 32-битного процесса.