Вы описали происхождение вашей проблемы следующим образом: «Я хочу, чтобы DLL импортировала некоторые символы из exe-файла» в комментарии к ответу Лучиана Григоре.Вы дополнительно написали в тексте своего вопроса, что хотите, чтобы «DLL находила эти символы в EXE-файле. Мы ожидаем, что DLL найдет эти символы в EXE-файле».
В основном это вопрос разработки, следует лиэкспортировать функции или данные из exe или нет.Обычно каждый создает экспорт только из DLL.Если EXE необходимо предоставить некоторую информацию в DLL, она предоставляет информацию по параметрам .Например, вы вызываете в EXE какую-то функцию MyFunc
, реализованную и экспортированную в DLL.В качестве дополнительного параметра MyFunc
вы получаете указатель context
, который может напрямую или косвенно получить DLL-библиотеку всей необходимой информации для EXE.
В некоторых редких ситуациях вы можете экспортировать данные или функции из EXE.Например, вы используете утилиту DumpBin.exe
(просто запустите «Командная строка Visual Studio (2010)», чтобы использовать ее), чтобы убедиться, что Outlook.exe экспортирует
DumpBin.exe /exports "C:\Program Files\Microsoft Office\Office14\OUTLOOK.EXE"
File Type: EXECUTABLE IMAGE
Section contains the following exports for outlook.exe
00000000 characteristics
4E79B6C8 time date stamp Wed Sep 21 12:04:56 2011
0.00 version
1 ordinal base
66 number of functions
66 number of names
ordinal hint RVA name
1 0 00B58A88 CleanupAddressComponents
2 1 00B58A88 CleanupNameComponents
3 2 00228DC4 DllCanUnloadNow
4 3 004848F8 DllGetClassObject
...
65 40 0038EF30 UpdateContactTracker
66 41 00902788 dwIsLoggingEnabled
Я могу объяснить, как вы можете реализовать сценарийбез долгих обсуждений, когда и нужно ли вам это делать.
Прежде всего, файл LIB содержит файлы OBJ, которые имеют другой формат: Исполняемый файл программы (PE) .Во время компиляции в общий файл будет помещен другой общий раздел.Очень важно, что исполняемый файл программы (EXE или DLL) содержит не только код, но и много дополнительной информации в заголовочной части PE.Наиболее важными являются
- Экспорт каталога
- Импорт каталога
- Импорт каталога таблиц адресов
- Базовый каталог перемещения
- Каталог ресурсов
Вы можете использовать утилиту DumpBin.exe
(просто запустите «Командная строка Visual Studio (2010)», чтобы легко ее использовать).Для просмотра информации о заголовках вы можете использовать DumpBin.exe /headers my.exe
.Для просмотра содержимого каталога экспорта вы можете использовать DumpBin.exe /exports my.exe
и т. Д.
Если вы компилируете DLL, которая экспортирует некоторые функции или данные, файл LIB будет создан дополнительно.Это так называется библиотека импорта .Если вы используете LIB в вашем проекте EXE, который использует некоторые функции или данные из DLL, компоновщик разрешит внешние ссылки и поместит в каталог импорта EXE информацию о функциях, которые должны быть разрешены во время загрузки..
Таким образом, библиотека импорта содержит только шаблоны для заполнения каталога каталогов импорта и импорта таблицы адресов в EXE.
В общем случае аналогичным образом можно экспортировать некоторые данные функций из EXE, создатьLIB, использует LIB в проекте DLL и таким образом реализует импорт некоторой информации в DLL из EXE.
Я сделал демонстрационный проект , который демонстрирует путь. Пожалуйста, внимательно прочитайте инструкции по компиляции в конце моего ответа, если хотите удалить все LIB из Проекта и создать все самостоятельно .Код ExportFromExe.c
(EXE):
//#define CREATE_IMPORT_LIBRARY_ONLY
#include <Windows.h>
EXTERN_C __declspec(dllexport) int someData = 0;
EXTERN_C __declspec(dllexport) int __stdcall myFunc (int x);
EXTERN_C __declspec(dllexport) int __stdcall MyFunc();
int __stdcall myFunc (int x)
{
return x + 10;
}
#ifndef _DEBUG
int mainCRTStartup()
#else
int main()
#endif
{
someData = 5;
#ifndef CREATE_IMPORT_LIBRARY_ONLY
return MyFunc();
#endif
}
Код MyDll.c
(DLL):
#include <Windows.h>
EXTERN_C __declspec(dllexport) int myData = 3;
EXTERN_C __declspec(dllimport) int someData;
EXTERN_C __declspec(dllimport) int __stdcall myFunc (int x);
#ifndef _DEBUG
EXTERN_C BOOL WINAPI _DllMainCRTStartup (HINSTANCE hinstDLL, DWORD fdwReason,
LPVOID lpvReserved)
#else
BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
#endif
{
if (fdwReason == DLL_PROCESS_ATTACH)
DisableThreadLibraryCalls(hinstDLL);
return TRUE;
UNREFERENCED_PARAMETER (lpvReserved);
}
EXTERN_C __declspec(dllexport) int WINAPI MyFunc()
{
return someData + myFunc(myData);
}
Для возможности успешного создания проекта наВ первый раз мы должны решить проблему: «кто был первым: курица или яйцо?»потому что проект EXE зависит от MyDll.lib
, а проект DLL зависит от ExportFromExe.lib
.Для первой компиляции EXE мы можем временно удалить $(OutDir)MyDll.lib
из настройки компоновщика проекта EXE и определить CREATE_IMPORT_LIBRARY_ONLY
.В результате мы создадим ExportFromExe.exe
и ExportFromExe.lib
.В более крупных проектах вместо этого можно использовать опцию компоновщика Undefined Symbol Only (/FORCE:UNRESOLVED)
.Затем мы можем построить MyDll
проект, который создает MyDll.dll
и MyDll.lib
.Теперь вы можете удалить CREATE_IMPORT_LIBRARY_ONLY
из EXE и включить $(OutDir)MyDll.lib
в качестве настройки компоновщика («Дополнительные Depandencies» в разделе «Input» настроек).Следующая сборка проекта EXE даст окончательное решение.
Я использовал несколько небольших хитростей для удаления C-Runtime и уменьшения размера EXE и DLL до 2,5 или 3 КБ.Таким образом, вы можете использовать /all
переключатель DumpBin.exe
для проверки полной информации из двоичных данных EXE и DLL включительно.
Поскольку EXE возвращает результаты как ERRORLEVEL, вы можете протестировать приложение в командной строке:
echo %ERRORLEVEL%
0
ExportFromExe.exe
echo %ERRORLEVEL%
18