В какой DLL есть PathCchAppend?

avatar
Ajay
5 августа 2019 в 08:32
640
2
2

Я пытаюсь условно использовать (, если доступно) функцию PathCchAppend. Я получил сигнатуру функции из заголовка pathcch.h. Однако когда я пытаюсь получить адрес функции из SHLWAPI.DLL, это не удается:

auto pca = GetProcAddress(GetModuleHandle(L"shlwapi.dll"), "PathCchAppend");

Используя Depends, я увидел, что этой функции нет в этой DLL (я использую Windows 10). pathcch.dll не существует, и, следовательно, его нельзя загрузить.

В какой DLL помещена эта функция?

РЕДАКТИРОВАТЬ: Спасибо за ответы. Здесь я нашел имена DLL, упомянутые в ответах ниже:

https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-81-api-sets

Источник
RbMm
5 августа 2019 в 08:54
0

в api-ms-win-core-path-l1-1-0.dll , поэтому вам понадобится GetProcAddress(LoadLibraryW(L"api-ms-win-core-path-l1-1-0.dll"), "PathCchAppend");

Ajay
5 августа 2019 в 08:56
0

Это не совсем хороший вариант! :( Он не совместим с прямой / обратной связью.

Ajay
5 августа 2019 в 09:02
0

Это подход к пересылке функций / API, созданный MS, верно? Так доработаны ли имена DLL? Где они задокументированы?

RbMm
5 августа 2019 в 09:10
0

это задокументировано в PathCchAppend - использование Pathcch.lib задокументировано. после сборки с Pathcch.lib - api-ms-win-core-path-l1-1-0.dll - это завершено в вашем exe dll

Ajay
5 августа 2019 в 12:48
0

В моем вопросе явно упоминается использование этой функции, если она доступна. Таким образом, существует функция-оболочка PathSafeAppend, которая будет использовать PathCchAppend, если она доступна, иначе PathAppend. Связывание с библиотекой не позволит загрузить изображение в более ранней ОС.

Remy Lebeau
5 августа 2019 в 16:45
2

@Ajay, если ваш компоновщик поддерживает отложенную загрузку, вы можете создать статическую ссылку на файл .lib, и его функции будут загружаться динамически во время выполнения при первом вызове вашего кода, а не во время загрузки. Вы можете использовать в своем коде ловушку задержки загрузки , чтобы обеспечить откат, если DLL или функции не загружаются. Это более безопасный и прозрачный вариант, чем использование GetProcAddress() вручную.

Ответы (2)

avatar
David Heffernan
5 августа 2019 в 08:59
4

Вы можете использовать инструмент DUMPBIN для извлечения этой информации из файла .lib:

dumpbin /headers /path/to/pathcch.lib

Затем вам нужно просмотреть вывод, чтобы найти нужную функцию. Например, это результат x64-версии файла lib:

  Version      : 0
  Machine      : 8664 (x64)
  TimeDateStamp: FFFFFFFF Sun Feb 07 06:28:15 2106
  SizeOfData   : 0000002E
  DLL name     : api-ms-win-core-path-l1-1-0.dll
  Symbol name  : PathCchAppend
  Type         : code
  Name type    : name
  Hint         : 5
  Name         : PathCchAppend

Что касается комментариев об обратной и прямой совместимости жесткого кодирования этого имени DLL, файл .lib жестко кодирует имя DLL. Поэтому, если вы ссылаетесь на функцию с помощью файла .lib, вы жестко кодируете зависимость для этой DLL. Это связывает Microsoft в договоре о продолжении экспорта этой функции из этой DLL в будущих выпусках Windows. И поэтому явное связывание с использованием LoadLibrary/GetProcAddress не более или менее безопасно, чем неявное связывание с использованием файла .lib из SDK.

Jonathan Potter
5 августа 2019 в 11:50
3

Microsoft явно не чувствовала себя особенно связанной, когда вынимала его из shlwapi.dll.

David Heffernan
5 августа 2019 в 11:58
0

@JonathanPotter Было ли это официальной функцией на тот момент или это было недокументировано?

RbMm
5 августа 2019 в 16:41
1

@JonathanPotter - в любом случае - используйте lib, где жестко запрограммирован api-ms-win-core-path-l1-1-0.dll не более безопасный, сравните явный вызов с LoadLibrary("api-ms-win-core-path-l1-1-0")

Ajay
6 августа 2019 в 05:16
0

Простое наблюдение, что этого файла нигде на диске нет, функция GetModuleHandle, тем не менее, работает успешно.

IInspectable
10 августа 2019 в 11:52
0

@jon: Насколько я помню, DLL, которая экспортировала любой заданный символ, никогда не была частью документированного контракта. Библиотека импорта была, и это не изменилось.

avatar
Thorsten Schöning
24 февраля 2022 в 03:42
1

api-ms-win-core-path-l1-1-0.dll не является реальной DLL или файлом на диске, вместо этого это только какое-то виртуальное имя, так что загрузчик может в конце отображать запросы на какой-либо диск в файле. Расширение DLL используется по соглашению или в качестве системного требования только загрузчиком, но также не подразумевает никакого файла.

Вы можете использовать имя набора API в контексте операции загрузчика, такой как LoadLibrary или P/Invoke, вместо имени модуля DLL, чтобы обеспечить правильный маршрут к реализации независимо от того, где API фактически реализован на текущем устройстве. . Однако при этом необходимо добавить строку .dll в конце имени контракта. Это требование загрузчика для правильной работы и фактически не считается частью имени контракта. Хотя в этом контексте имена контрактов кажутся похожими на имена DLL, они принципиально отличаются от имен модулей DLL и не ссылаются напрямую на файл на диске.

https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-apisets#api-set-contract-names

Итак, настоящий ответ на вопрос: KernelBase.dll. Это важно для случаев использования, подобных моему, где мне нужно создать файл lib на основе реальной DLL, что возможно только с KernelBase.dll. MS поддерживает некоторые дополнительные документы, что также делает доступным базовый файл некоторого набора API.