Если я использую Win32 API LoadLibrary для загрузки того же DLL 3 раза подряд, он должен возвратить 3 отличных дескриптора и функции в каждой библиотеке, у всех должны быть различные корректные адреса? (Или это делает что-то "умное" и обнаруживает, если dll был уже загружен для процесса и просто указывает на тот же модуль?)
Она делает что-то умное. Windows ведет счетчик ссылок для каждой DLL, загруженной через LoadLibrary. Вот почему вы должны вызывать FreeLibrary один раз для каждого соответствующего вызова LoadLibrary. Если вы не освободите DLL первой, каждый вызов LoadLibrary даст вам один и тот же хэндл.
Из документации MSDN по FreeLibrary:
Каждый процесс ведет счетчик ссылок для каждого загруженного библиотечного модуля. Этот счетчик ссылок увеличивается при каждом вызове LoadLibrary и уменьшается при каждом вызове FreeLibrary.
Если это одна и та же DLL, то она не будет загружать ее снова.
http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx
"Если указанный модуль является DLL, которая еще не загружена для вызывающего процесса, система вызывает функцию DllMain DLL со значением DLL_PROCESS_ATTACH. Если DllMain возвращает TRUE, LoadLibrary возвращает хэндл к модулю. Если DllMain возвращает FALSE, система выгружает DLL из адресного пространства процесса, а LoadLibrary возвращает NULL. Вызывать LoadLibrary из DllMain небезопасно. Для получения дополнительной информации см. раздел Remarks в DllMain."
"Если lpFileName не включает путь и существует более одного загруженного модуля с одинаковым базовым именем и расширением, функция возвращает хэндл модуля, который был загружен первым."
.Нет, не работает. Чтобы обойти это, вы можете скопировать .dll во временный файл (столько раз, сколько вам нужно для загрузки .dll), а затем удалить файлы, как только вы закончите.