Быстрый поиск

Выбрать раздел :
Выбрать форум :
Критерии сортировки результатов поиска :
Порядок сортировки :
Искать сообщения :
 
Опции темы  Поиск в этой теме 
ksili
Всего баллов:
4,113
Статусных баллов:
3,613
коричневый пояс
22.09.2009 02:55
Проблема взаимодействия 32-битного приложения и 64-битной библиотеки

Разрабатывается 32-разрядное приложение. Сначала оно делалось под Windows XP, потом заказчик захотел, чтобы оно работало и под Висту с 7-кой. Поправили. Но теперь он возжелал, чтобы оно ещё работало и в 64-разрядных версиях Висты и Win7. И вот здесь появилась проблема. Специфика программы такова, что она внедряет во все другие визуальные приложения свою DLL. А затем в некоторых случаях общается с ними посредством сообщений.

В 64-битных виндах было замечено, что не все приложения "контачат" с нашим. Оказалось, что 32-битные приложения в Windows не могут загружать 64-битные DLL (и наоборот), а в 64-битные процессы может быть внедрена только 64-битная DLL. Соответственно все 64-битные программы оказывались для нас как бы невидимы.

Был найден следующий выход. Собираются 2 версии нашей библиотеки 32 и 64-бит. Основная программа после внедрения 32-битной библиотеки проверяет, не 64-битная ли Windows? Если да, то запускается отдельная 64-битная программа (без окна), которая уже внедряет 64-битную версию той же DLL (которой передаётся хэндл основной программы, чтобы она знала, с кем общаться).

И вот здесь имеено проблема: 64-битная DLL загружается, но не внедряется. Дальше приведу код с комментариями. Может я вообще что-то не то делаю?

Полностью весь код того маленького 64-битного приложения, которое должно внедрить 64-битную библиотеку:

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include "../Inc/trace.h"

int _tmain(int argc, _TCHAR* argv[])
{
if(argc == 2)
{
int _hwnd;

if(!wcscmp(argv[1], L"-unload"))
_hwnd = 0;
else
_hwnd = _wtoi(argv[1]);

HMODULE hookDll = LoadLibrary(_T("FWHook64.dll")); //  загружаем DLL
if(hookDll)
{
if (_hwnd == 0) trace(true, " 64-bit DLL unloaded\n");
else trace(true, " 64-bit DLL loaded\n");

bool res = false;
BOOL (WINAPI *SetFWHookProc)(DWORD dwThreadId, HWND wndServerWindow);
(FARPROC&)SetFWHookProc = GetProcAddress(hookDll, "SetFWHook"); // ищем в ней нужную функцию

if(SetFWHookProc)
{
trace(true, " SetFWHook procedure found\n");

if(_hwnd)
res = SetFWHookProc(0, (HWND)_hwnd);
else
res = SetFWHookProc(-1, NULL);

if(res) trace(true, " SetFWHook complete succesful\n");
else trace(true, " SetFWHook complete unsuccesful\n");
}
FreeLibrary(hookDll);

}
return 0;
}

trace'ы это запись в лог. В функции SetFWHook просто ставится или снимается глобальный хук при помощи функции SetWindowsHookEx:

SetWindowsHookEx(WH_GETMESSAGE, GetPostMsgProc, g_hinstDll, dwThreadId);

В логе запись "64-bit DLL loaded" появляется, однако запись "SetFWHook procedure found" не появляется никогда. То есть получается, что функция GetProcAddress не выполняется. MSDN говорит, что эта функция находится в Kernel32.dll, что косвенно говорит о том, что в 64-й винде она может быть реализована по-другому? Или надо использовать другую функцию?

Какие ещё идеи?

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

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

ksili
Всего баллов:
4,113
Статусных баллов:
3,613
коричневый пояс
23.09.2009 02:22
Рейтинг
 
#1
Даа. Видимо не в тот раздел вопрос задал. Вот только подходящего раздела, похоже, нет...


Alexey Kukanov (Intel)
Всего баллов:
13,396
Статусных баллов:
13,396
черный пояс
13.10.2009 03:21
Рейтинг
 
#2
ksili, в коде ничего противоестественного не видно; по-моему, всё должно бы работать. Сам я с такими проблемами не сталкивался раньше. Первое, что приходит в голову в качестве объяснения - какие-нибудь незначительные различия в именах функций, к примеру из-за разных соглашений о вызове. Но это элементарно проверить, что вы наверняка уже и сделали.

Если разберётесь или уже разобрались, в чём дело - сообщите, мне любопытно :)


ksili
Всего баллов:
4,113
Статусных баллов:
3,613
коричневый пояс
14.10.2009 03:33
Рейтинг
 
#3 Ответ на #2
Цитирую -Alexey Kukanov (Intel)
ksili, в коде ничего противоестественного не видно; по-моему, всё должно бы работать. Сам я с такими проблемами не сталкивался раньше. Первое, что приходит в голову в качестве объяснения - какие-нибудь незначительные различия в именах функций, к примеру из-за разных соглашений о вызове. Но это элементарно проверить, что вы наверняка уже и сделали.

Если разберётесь или уже разобрались, в чём дело - сообщите, мне любопытно :)

Ошибка оказалась глупая. Я библиотеку к проекту не подключил (LIB-файл не прописал). Поэтому при её подгрузке приложение видело декорированные имена функций. А догадался я до этого случайно, в процессе опытов: узнал как выглядит декорированное имя функции и в dll указал, чтобы нужная функция экспортировалась под конкретным именем при компиляции под x64:

#ifdef _M_AMD64
#pragma comment(linker, "/export:MyFunction=?MyFunction@@YAHKPEAUHWND__@@@Z")
#endif

После этого функция по своему обычному имени стала находиться.



ksili
Всего баллов:
4,113
Статусных баллов:
3,613
коричневый пояс
19.10.2009 04:16
Рейтинг
 
#4 Ответ на #3
Цитирую -ksili

После этого функция по своему обычному имени стала находиться.

То, что функция стала находиться само по себе проблему не решило. Она выполняется неуспешно. Пока решению проблемы мешает то, что из этой функции не пишутся записи в лог-файл. Почему - пока не понятно. Поэтому приходится самому пытаться догадываться.

У меня пока следующее предположение: одним из параметров этой функции является HWND окна 32-битного приложения. Т.е. он получается в 32-битном приложении и является 32-битным. Затем он передается в качетсве параметра командной строки (в текстовом виде) 64-битному приложению. А оно уже приводит его обратно к HWND. Вот только в 64-битном приложении HWND уже 64-битный. И я не знаю, являются ли HWND, полученные в 32-битной программе, корректными для 64-битных программ? Сможет ли оно потом его использовать, чтобы послать сообщение 32-битной программе?

Например, получен хэндл 0x12345678, в 64-битной программе он приводится к виду 0x0000000012345678. Если затем, он будет использован как хэндл окна, которому надо передать сообщение, то дойдёт ли это сообщение до исходного 32-битного приложения?



Alexey Kukanov (Intel)
Всего баллов:
13,396
Статусных баллов:
13,396
черный пояс
22.10.2009 09:16
Рейтинг
 
#5 Ответ на #4
Цитирую -ksili

То, что функция стала находиться само по себе проблему не решило. Она выполняется неуспешно. Пока решению проблемы мешает то, что из этой функции не пишутся записи в лог-файл. Почему - пока не понятно. Поэтому приходится самому пытаться догадываться.

У меня пока следующее предположение: одним из параметров этой функции является HWND окна 32-битного приложения. Т.е. он получается в 32-битном приложении и является 32-битным. Затем он передается в качетсве параметра командной строки (в текстовом виде) 64-битному приложению. А оно уже приводит его обратно к HWND. Вот только в 64-битном приложении HWND уже 64-битный. И я не знаю, являются ли HWND, полученные в 32-битной программе, корректными для 64-битных программ? Сможет ли оно потом его использовать, чтобы послать сообщение 32-битной программе?

Например, получен хэндл 0x12345678, в 64-битной программе он приводится к виду 0x0000000012345678. Если затем, он будет использован как хэндл окна, которому надо передать сообщение, то дойдёт ли это сообщение до исходного 32-битного приложения?


Насколько я могу судить по прочитанному в MSDN, дескрипторы окна могут переноситься из 32 в 64 разрядный процесс, при этом для преобразования нужно пользоваться функцией LongToHandle. Вроде как дескриптор окна - знаковое целое, а преобразование, которое вы используете, не учитывает знака.

ksili
Всего баллов:
4,113
Статусных баллов:
3,613
коричневый пояс
22.10.2009 21:26
Рейтинг
 
#6 Ответ на #5
Спасибо! Об этом я не догадывался.




Статистика форума

246 пользователей 277 тем и 2036 сообщений.
За последние 24 часа появилось 0 новых тем 0 новых сообщений и 0 новых пользователей

Самая популярная тема за последние 3 дня Найди ошибки. Пример 2. Больше всего ответов отправлено на сообщение Найди ошибки. Пример 2. Наибольшее количество просмотров у сообщения Здравствуйте,П

Приветствуем нового пользователя chat1983