Экспорт функции из ехе-файла

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Koduc
Сообщения: 22
Зарегистрирован: 10 сен 2007, 01:33
Контактная информация:

25 дек 2007, 04:26

Создаю простенький ехе-файл с экспортом из него фукции:

Код: Выделить всё

__declspec(dllexport) void Start_all(void);
void Start_all()
{
 ::MessageBox(NULL,"Running!","Running!",0);
}
компилирую, проверяю на экспорты - функция экспортируется и видна в PE Explorer'e и dumpbin'e.
Пытаюсь в другом ехе импортировать эту функцию:

Код: Выделить всё

typedef void (*cfunc)();
cfunc DllFunc;
HMODULE hDll = LoadLibrary("_small.exe");
if(hDll == NULL)
 return;
DllFunc = (cfunc)GetProcAddress((HMODULE)hDll, "?Start_all@@YAXXZ");
if(DllFunc == NULL)
 return;
DllFunc();
FreeLibrary(hDll);
Адреса получаю нормальные, но при DllFunc(); падает в Access Violation. Как заставить работать? Заранее благодарен..
Аватара пользователя
WinMain
Сообщения: 913
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

25 дек 2007, 11:16

Вызывать импортируемые функции можно только из DLL-модулей.
BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

25 дек 2007, 11:37

WinMain писал(а):Вызывать импортируемые функции можно только из DLL-модулей.
Вызывает сомнения. Писали мы одну систему, там запросто DLL-и использовали функции, экспортируемые главной EXE-шкой. Причем, линковка была статическая (т.е. через lib-файл, а не через LoadLibrary)
Может, отличие нашего случая от этого в том, что EXE-шка запускалсь первой, т.е. на момент вызова DLL-ю функции из EXE, та (т.е. EXE) уже была загружена. А здесь (ну этоя сильно "на пальцах" предполагаю) не пытается ли EXE-шка как-нибудь стартовать и именно на этом и происходит падение?
Аватара пользователя
WinMain
Сообщения: 913
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

25 дек 2007, 11:47

Всё дело в том, что когда мы подгружаем DLL-модуль, то он становится частью нашего процесса и имеет с ним одно общее адресное пространство. В то же время ЕХЕ-файл - это отдельный процесс и у него отдельное адресное пространство, он при загрузке не линкуется с загружающим его процессом. Это всё равно что звонить по телефонному справочнику какого-то одного города, не зная о том, что ты находишься совсем в другом городе.

Т.е. в данном случае функция __declspec(dllexport) void Start_all(void) должна находиться в DLL-модуле, а не в ЕХЕ-файле.
Koduc
Сообщения: 22
Зарегистрирован: 10 сен 2007, 01:33
Контактная информация:

25 дек 2007, 12:21

BBB писал(а):Может, отличие нашего случая от этого в том, что EXE-шка запускалсь первой, т.е. на момент вызова DLL-ю функции из EXE, та (т.е. EXE) уже была загружена. А здесь (ну этоя сильно "на пальцах" предполагаю) не пытается ли EXE-шка как-нибудь стартовать и именно на этом и происходит падение?
Да, интересно получается..
Вариант первый: выполняю ехе, подгружаю из него библиотеку, в библиотеке беру функцию из ехе и вызываю её, все нормально отрабатывает.
Вариант второй: выполняю второй ехе, из него пытаюсь вызвать функцию из первого ехе, падает..
Видимо с адресами что-то не так.. При экспорте из ехе получается что все относительные адреса в нем проецируются в память по другим адресам.. Указатель на функцию получаем правильный, но сама функция уже начинает вызывать функции по "неправильным" адресам.. Я правильно понимаю? как такое исправить можно?
Во вложении тестовые ехе с исходниками.
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Koduc
Сообщения: 22
Зарегистрирован: 10 сен 2007, 01:33
Контактная информация:

25 дек 2007, 12:24

WinMain писал(а):Всё дело в том, что когда мы подгружаем DLL-модуль, то он становится частью нашего процесса и имеет с ним одно общее адресное пространство. В то же время ЕХЕ-файл - это отдельный процесс и у него отдельное адресное пространство, он при загрузке не линкуется с загружающим его процессом. Это всё равно что звонить по телефонному справочнику какого-то одного города, не зная о том, что ты находишься совсем в другом городе.
Получается что так, значит я немного в правильную сторону думал.. Как тогда можно выполнить поставленную задачу? Загружать ехе в память, разбирать по заголовкам и секциям, вызывать функции со смещением? проще нет способа? :)
Аватара пользователя
WinMain
Сообщения: 913
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

25 дек 2007, 12:49

Koduc писал(а): Вариант второй: выполняю второй ехе, из него пытаюсь вызвать функцию из первого ехе, падает..
Видимо с адресами что-то не так.. При экспорте из ехе получается что все относительные адреса в нем проецируются в память по другим адресам.. Указатель на функцию получаем правильный, но сама функция уже начинает вызывать функции по "неправильным" адресам.. Я правильно понимаю? как такое исправить можно?
Я уже привёл аналогию, когда ты звонишь по местным городским телефонам, но при этом пользуешься телефонным справочником другого города...

Фактически загружаемый ЕХЕ-файл должен стать частью твоего вызывающего процесса. Но на этот счёт Windows не предоставляет документированных возможностей. Либо твой вызывающий процесс должен внедриться в вызываемый процесс. Т.е. тебе нужно будет написать что-то типа вируса. Но это уже отдельная технология программирования.
Реально можно сделать вызываемый ЕХЕ-файл в виде СОМ-сервера, а свой вызывающий процесс сделать СОМ-клиентом. Тогда всё будет нормально. Ты сможешь вызывать нужные тебе функции через СОМ-интерфейсы.

Наиболее простой способ - это запускать приложение и передавать ему параметры через командную строку. Тогда, в зависимости от тех или иных параметров, приложение будет вызывать ту или иную функцию.
Koduc
Сообщения: 22
Зарегистрирован: 10 сен 2007, 01:33
Контактная информация:

25 дек 2007, 13:16

WinMain писал(а):Наиболее простой способ - это запускать приложение и передавать ему параметры через командную строку. Тогда, в зависимости от тех или иных параметров, приложение будет вызывать ту или иную функцию.
Я не спорю, что так было бы намного проще ;) Но необходим вызов функций в контексте вызывающего процесса.. Придется видимо копать в сторону загрузки exe из памяти..
Ни у кого нет загрузчика из памяти с нормальными коментариями? :) А то где ни посмотришь, везде непонятные махинации со сдвигами..
BBB
Сообщения: 1272
Зарегистрирован: 27 дек 2005, 13:37

25 дек 2007, 13:48

Koduc,
Вот тут обсуждение на близкую тему. Может, если не поможет, то что-то прояснит:
http://www.wasm.ru/forum/viewtopic.php?id=13377

А вообще, что за задача такая хитрая? Учебная или "живая"? Этот самый EXE - самодельный (исходник есть)? Или есть некий чужой EXE-шник без исходников, который требуется попользовать?

UPD.
Тут вроде что-то о преобразовании EXE в DLL:
http://www.forth.org.ru/~pinka/lib/Tools/readme.txt
http://www.forth.org.ru/~pinka/lib/Tools/
Koduc
Сообщения: 22
Зарегистрирован: 10 сен 2007, 01:33
Контактная информация:

25 дек 2007, 14:19

BBB писал(а):Koduc,
А вообще, что за задача такая хитрая? Учебная или "живая"? Этот самый EXE - самодельный (исходник есть)? Или есть некий чужой EXE-шник без исходников, который требуется попользовать?
Спасибо, почитаю сейчас.
Задача "живая". Есть некая коммерческая программа, к ней идут модули в виде dll. Моя задача сделать чтобы модули можно было и из exe подключать (получается что через длл). К первоначальной программе само собой у меня дсотупа нет, зато длл и подключаемый ехе уже на моей совести.
Ответить