2011-12-13 3 views
4

Прежде всего, пожалуйста, простите меня за то, что я не знаю правильной терминологии, я уверен, что для этого есть очень общее техническое название, которое я могу просто помочь Google, но я не могу найти помощь, если я не знаю, для начала.Коллекция DLL в другой назначенной папке?

Я строю модульную систему в Delphi 7. Есть несколько приложений и множество DLL. Все приложения используют эти DLL, а также некоторые DLL используют другие DLL. DLL в настоящее время сохранены в том же месте, что и приложение. Вместо этого я хотел бы поместить все эти DLL в подпапку (в другом месте от EXE), но, конечно, Delphi не будет знать, как их найти.

Есть ли способ, которым я могу направить свои приложения Delphi в определенную директорию для DLL? Он не может использовать Contantants, потому что будет возможность указать, где хранятся библиотеки DLL.

Эти библиотеки DLL - это простая коллекция функций StdCall в каждой, ничего особенного.

EDIT:

Чтобы объяснить причину, почему я хочу, чтобы держать DLL в их собственной папке: Эта система Я здание рассматривает эти DLL в качестве дополнения. По умолчанию система может даже не иметь никаких надстроек. С другой стороны, это также позволит различным производителям создавать другие DLL и включать их в качестве надстроек. Затем каждое приложение, требующее этих надстроек, будет направлено в папку, где их можно найти. Приложение будет иметь собственные DLL, которые будут находиться в том же каталоге, что и приложения. Но DLL Vendors's я хотел бы сохранить отдельно.

Как уже упоминалось в нижеприведенных ответах, наилучшим вариантом было бы реализовать метод импорта DLL, поскольку A) Я могу указать путь для каждой импортируемой DLL, B) Я могу лучше контролировать использование каждой DLL (Does он должен быть загружен или нет?) и C) Каждая DLL может быть технически находиться в отдельных папках сама по себе (вендоры могут захотеть создать собственную структуру папок). Эта система все еще очень зрелая, но я планирую сделать ее более гибкой.

+2

Возможно, вы хотите [установить PATH] (http://edn.embarcadero.com/article/28254) –

+0

@PeterTurner Нет, это не поможет, потому что у меня много разных DLL - некоторые могут быть в другом чем другие. Кроме того, я добавил больше к моему вопросу, чтобы объяснить, почему. –

ответ

4

Вы можете сделать это с помощью PATH, но я не рекомендую этого. Это жестокий и негибкий подход. И, конечно же, вам необходимо изменить системную PATH, чтобы она имела какое-либо влияние на время загрузки.

Вы можете загрузить свои DLL явно с LoadLibrary и GetProcAddress. Это не забавно, если есть много импорта, но в противном случае это может быть хорошим вариантом. И помните, что если вы спуститесь по этому маршруту, каждая DLL должна переключиться на явное соединение.

Есть что-то по имени DLL Redirection, но MS не рекомендую вам это использовать. Они рекомендуют использовать бок о бок компоненты. Сказав это, команда Visual Studio переместила в сторону из боковых компонентов со временем выполнения MSVC в VS2010 из-за боли, которую бок о бок вызвал в предыдущем выпуске.

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

Update

Обновление на ваш вопрос дает дополнительную информацию, что эти библиотеки DLL являются факультативными дополнениями.В этом случае у вас просто нет альтернативы, кроме как использовать явное соединение с LoadLibrary и GetProcAddress.

+0

+1 Спасибо за информацию - учитывая конкретный сценарий этого проекта (я добавлю комментарий по разъяснению вопроса), лучшим решением будет использование метода импорта. –

+0

Помните, что вам нужно заменить каждую «процедуру ... внешним» на переменную, содержащую процедуру, вызов LoadLibrary и вызов GetProcAddresss и проверку ошибок. Если вы спуститесь по этому маршруту, заверните его в класс, чтобы избежать дублирования. У меня есть такая библиотека для ситуаций, когда я не могу избежать «GetProcAddress». –

+0

Это идеальный вызов, который я люблю принимать: D –

2

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

Если вы действительно хотите пойти по пути размещения DLL в отдельной папке, вам нужно знать, можете ли вы загружать библиотеки DLL с помощью API LoadLibrary, который также позволяет специфицировать путь. Однако, если DLL статически загружается, то это Windows, которая выполняет поиск. Сначала поиск в Windows выглядит в папке приложения, затем выполняется поиск в Windows PATH. Кроме того, поскольку Delphi 7 создает только 32-битные приложения, это может стать беспорядочным под Windows 64-разрядным.

+0

Нет проблем с 64-битными окнами, которые я вижу. В противном случае я не мог согласиться больше. –

+0

Это почти ответ на мой вопрос - с моим заключением заключается в том, чтобы реализовать способность импортировать их (что в моем конкретном сценарии действительно будет лучшим выбором в любом случае). –

+0

@ David: в прошлом мы поместили общие библиотеки DLL в папку windows \ system32. В 64-разрядной версии Windows 32-разрядные приложения не имеют доступа к system32. См. Эту ссылку для получения дополнительной информации: http://msdn.microsoft.com/en-us/library/aa384187%28v=vs.85%29.aspx – Steve

2

В Windows есть «DLL search order». Один из этих путей поиска - The directory from which the application loaded, поэтому он работает, чтобы иметь их в той же папке, что и EXE.

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

Если вы динамически связываетесь с DLL, вы можете использовать LoadLibrary/LoadLibraryEx для загрузки DLL во время выполнения кода. Используя эти функции, вы должны указать путь к DLL, поэтому библиотеки DLL могут быть в любом месте. В этом случае я считаю, что для размещения библиотек в отдельной папке достаточно держать вещи в порядке. Пока вы не ставите библиотеки DLL в общую папку, такую ​​как папка Windows System32, вы избегаете много головных болей.

+1

+1 для отличной ссылки – Steve

+0

Если все, что вы предоставляете, это поисковый запрос и ссылка, это должен быть комментарий. –

+0

@KenWhite На самом деле, поисковый запрос и/или ссылка в этом случае совершенно прекрасны, возникает вопрос, что я буду искать сам, если бы знал, что искать. Но опять же, этот ответ по-прежнему не обязательно решает мою проблему, он просто предоставляет некоторую полезную информацию этому вопросу. –

4

Если вы динамически загружаете библиотеки DLL в свой код, вы можете хранить их в любом месте, так как в любом случае вы должны пройти полный путь до LoadLibrary/Ex(). Если вы статически ссылаетесь на библиотеки DLL, вы можете использовать SetDllDirectory(), чтобы назначить дополнительный путь для включения в путь поиска DLL ОС.

+1

'SetDllDirectory' полезен только при вызове LoadLibrary. Неплохо для неявной ссылки из exe. –

+0

Если он использует DLL для реализации дополнений, он не может использовать статические ссылки. –

+1

'SetDllDirectory()' применяется как к динамической загрузке, так и к статической привязке. Путь поиска DLL всегда используется для статической привязки, поскольку загрузчик ОС имеет только имя DLL, но не его путь, поэтому он должен искать файл. Для динамической загрузки путь поиска применяется только в том случае, если неавтоматический путь передается в «LoadLibrary/Ex()». –

0

temporarly решения:

Вы можете установить путь DLL в ярлыке вашего приложения (в разделе «Начало в» окне).