2009-08-18 1 views
17

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

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

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

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

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

Geeko

ответ

7

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

  • Использование .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(); 
} 
+0

спасибо Микаэль, вы очень ответили на мои вопросы, кроме одного: существует ли способ сделать неявное связывание, используя только файлы DLL. еще раз спасибо – geeko

+0

Я действительно ценю вашу работу Майкла. , но этот код предназначен для явной привязки. Не могли бы вы назвать имена этих инструментов? или, по крайней мере, запрос, который вы использовали для их получения? – geeko

+0

Запрос был просто «Создать lib из dll», одним из лучших хитов был проект codecroject. – Michael

Смежные вопросы