Подтвердить что ты не робот

Зачем нам нужен файл .lib-заглушки, когда у нас есть реальная реализация .dll?

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

не являются ли таблицы экспорта и относительного адреса достаточными для такого соединения?

так или иначе, с помощью которого можно делать неявное связывание, используя только .dll без файлов .lib stub/proxy?

Я думал, что исполняемый загрузчик Windows просто выполнил вызовы LoadLibrary/LoadLibraryEx от имени программы (отсюда и название неявного связывания), что является основным отличием от явной привязки. если это правда, то делать это явно без .lib должно указывать, что это выполнимо без него неявно, правильно? или я просто говорю не смысл?

любая помощь приветствуется, большое спасибо:)

Geeko

4b9b3361

Ответ 1

Я могу придумать несколько причин.

  • Использование .lib файлов означает, что вы можете создавать для другой версии DLL, чем в вашей системе, при условии, что у вас установлен правильный SDK.
  • Компиляторы и компоновщики должны поддерживать кросс-платформенные компиляции. Возможно, вы создаете для 64-битной цели на 32-битной платформе и наоборот и не имеете правильной библиотеки DLL.
  • .lib файлы позволяют вам "скрыть" определенные части вашей реализации - вы можете иметь частный экспорт, который не отображается в .lib, но доступен для обнаружения через GetProcAddress. Вы также можете делать порядковый экспорт, и в этом случае у них нет дружественного имени, экспортированного, но будет иметь дружественное имя в .lib.
  • У родной DLL нет сильных имен, поэтому может быть возможно найти неправильную версию DLL.
  • И самое главное, эта технология была разработана в 1980-х годах. Если бы он был разработан сегодня, он, вероятно, был бы ближе к тому, что вы описали - например,.NET вам просто нужно ссылаться на целевую сборку, и у вас есть все необходимое для ее использования.

Я не знаю, как сделать неявное связывание исключительно с DLL. Быстрый поиск показал несколько инструментов, но я не использовал их.

В этом случае я бы создал отдельный исходный файл с функциями, которые вам нужно использовать, и динамически загружать DLL и связывать их по мере необходимости. Например:

// using global variables and no-error handling for brevity.

HINSTANCE theDll = NULL;
typedef void (__stdcall * FooPtr)();
FooPtr pfnFoo = NULL;
INIT_ONCE initOnce;

BOOL CALLBACK BindDLL(PINIT_ONCE initOnce, PVOID parameter, PVOID context)
{
    theDll = LoadLibrary();
    pfnfoo = GetProcAddress(dll, "Foo");

    return TRUE;
}

// Export for foo
void Foo()
{
    // Use one-time init for thread-safe lazy initialization
    InitOnceExecuteOnce(initOnce, BinDll, NULL, NULL)
    pfnFoo();
}