BishP Ответов: 1

Невозможно вызвать 32-разрядную неуправляемую библиотеку DLL из 64-разрядного управляемого кода


Всем привет,
Мне очень жаль, если этот вопрос уже был задан. И извините за длинный пост.

Вот в чем моя проблема.

У меня есть 64-битный vb.net применение.
У меня есть сторонняя 32-битная неуправляемая DLL.
Мне нужно установить связь между 64-битным управляемым приложением и 32-битной неуправляемой библиотекой dll.
Вот вещи, которые я пробовал:

1. Я создал 32-бит vb.net обертка библиотеки классов, называемой порт COM1, и добавил vb.net com-класса, которая вызывает 32-бит воздействию неуправляемых функций dll файлы.
В проекте была включена функция "регистрация для COM-взаимодействия".
Когда я ссылался на 32-битную библиотеку DLL (COM1.dll) к моему 64-битному приложению и выполнил приложение, я получил следующее исключение:
"Не удалось загрузить файл или сборку "COM1.dll"...Была предпринята попытка загрузить программу с неправильным форматом."

2. Я создан 64-битной vb.net обертка библиотеки классов, называемой com2 и добавил vb.net com-класса, которая вызывает 32-бит неуправляемой библиотеке DLL.
В проекте была включена функция "регистрация для COM-взаимодействия".
Когда я сослался на 64-разрядные библиотеки DLL (COM2.dll)в моей 64-разрядные приложения и выполняется приложение, я был в состоянии загрузить 64-разрядные библиотеки DLL, но я получил следующее исключение, когда я позвонила одной из функций подвергается в неуправляемой библиотеке DLL (через 64-разрядная оболочка DLL):
"Была предпринята попытка загрузить программу с неправильным форматом."

Я понимаю, что не могу вызвать 32-битную dll непосредственно в свое 64-битное приложение.
То, что я пытаюсь сделать,-это вызвать 32-битную dll через механизм IPC; в данном случае COM.
Но, очевидно, я совершаю здесь какую-то ошибку.

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

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

Спасибо, что прочитали и уделили мне свое время.
Очень ценю вашу помощь.

С уважением.

Что я уже пробовал:

- Мой ком-класс

&ЛТ;comclass(comclass1.идентификатор classid, comclass1.interfaceid,="" comclass1.eventsid)=""&ГТ; _
Общественные ComClass1 Класс
Общественные объявить суб InitializePort либерал "I2CDrvrs" (I2cAddr бывал как байт, бывал evalBoardUsed как байт)
#Регионе "ком идентификаторы GUID"
"Эти GUID обеспечивают com-идентификатор для этого класса
и COM-интерфейсов. Если вы измените их, существующие
- клиенты больше не смогут получить доступ к классу.
Общественные константный идентификатор classid как String = "bd248311-07ca-4d09-a5d1-d4c6b4df0256"
Public Const InterfaceId As String = " f8de730a-d845-44c3-b029-fc556d2e7f0c"
Public Const EventsId As String = " abaf2635-6f30-46f7-a7a9-5a44bef46f9b"
#Конечный Регион

"У создаваемого COM-класса должна быть публичная суб-новая()
- без параметров, иначе класс не будет
"зарегистрирован в реестре COM и не может быть создан
- через CreateObject.
Общественные Саб Новый()
Ключевое слово mybase.Новый()
Конец Подводной Лодки
Конец Класса

Мой 64-разрядное приложение
Публичная функция foo () как логическая
Попробуй
COM1.ComClass1.InitializePort(2, 2)
Поймать ex как исключение
MsgBox(ex. ToString)
Конец Попытки

вернуть true
Конечная Функция

Richard MacCutchan

Вы не можете смешивать 32-и 64-битный код в одном адресном пространстве.

BishP

Да, я не пытаюсь вызвать 32-битную dll из того же адресного пространства. В данном случае я пытаюсь вызвать его через IPC, COM.

Richard MacCutchan

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

BishP

Итак, есть ли способ вызвать 32-битные dll-API из моего 64-битного приложения?

Richard MacCutchan

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

BishP

- Спасибо, Ричард. Я пробовал эту технику из этого блога: https://blog.mattmags.com/2007/06/30/accessing-32-bit-dlls-from-64-bit-code/

Richard MacCutchan

Похоже, работы много.

BishP

Спасибо за терпение, Ричард. :)
Я опубликую решение, если найду его.

Matt T Heffron

Как было сказано выше, вы не можете смешивать их в одном адресном пространстве.
Вам нужно запустить 32-битный COM-сервер как отдельный процесс.
(Внепроцессный COM-сервер.)
Давным-давно я знал магическое заклинание, чтобы сказать COM запустить DLL в отдельном процессе, но эти ячейки памяти не работают. :-)
Насколько я помню, это был довольно простой вариант регистрации COM-сервера.
COM будет запускать службу в своем собственном процессе и выполнять маршалинг между процессами.

1 Ответов

Рейтинг:
0

BishP

Я нашел довольно простое решение своей проблемы. Я реализовал модель клиент-сервер, используя методы и свойства класса сокетов. Я запускаю 32-битный код управляемой службы, работающий как сервер. Сервер выполняет функции 32-бит неуправляемой библиотеке DLL. Таким образом, сервер выступает в качестве обертки для неуправляемой библиотеке DLL. Я использую свое 64-битное приложение в качестве клиента. Я передаю строку на сервер от моего клиента. Строка содержит информацию о вызываемой функции и ее аргументах. Я разбираю строку на сервере и вызываю соответствующую функцию в неуправляемой dll.


Dave Kreskowiak

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

Как вы уже выяснили, единственное решение - это два отдельных процесса, один 32-битный и один 64-битный.

Richard MacCutchan

Почему бы просто не преобразовать 32-битную библиотеку в 64 или 64-битное приложение в 32?