Почему у этих библиотек две идентичные точки входа? - PullRequest
0 голосов
/ 04 октября 2018

Сегодня, работая над кодом VB.NET, мне пришлось получить доступ к двум внешним DLL, чтобы использовать некоторые методы.Разделы справки, которые я нашел, подсказали мне использовать следующие внешние методы:

Однако, когда я попытался вызвать эти методы из своего кода, я получил ошибкуговорят, что точки входа не существует.Поэтому я провел небольшое исследование и обнаружил, что библиотеки DLL в моей операционной системе (32-разрядная версия Windows 7 Enterprise) не включают эти методы точно, но вместо этого я получил:

  • PathIsNetworkPath → PathIsNetworkPath A / PathIsNetworkPath W
  • WNetAddConnection2 → WNetAddConnection2 A / WNetAddConnection2 W
  • WNetCancelConnection2 → WNetCancelConnection2 A / WNetCancelConnection2 W

Итак, я проверил их поведение: * Методызаканчивая с "А" работой, как и ожидалось.* Методы, заканчивающиеся на «W», не работают должным образом, они вызывают ошибки или возвращают неверные результаты (например, «false», когда должно быть «true»).И все же, однако, никто в разделах справки не упоминает о схожей проблеме.

Поэтому я провел небольшое исследование, и в MSDN документации я обнаружил, что библиотеки DLL содержаттолько те методы, которые заканчиваются на «A» и «W», и оба из них, в трех случаях, которые я использую, страницы документации идентичны, насколько я вижу.На самом деле по всей странице они не используют имя метода, который заканчивается на A / W, но без него.

Итак, мои вопросы: * почему у меня есть методы "A"и "W" вместо того, чтобы без A / W в моих DLL?В чем разница между ними обоими?Почему методы «А» работают у меня, а методы «W» - нет?

1 Ответ

0 голосов
/ 04 октября 2018

Начиная с Windows NT 4/2000 / XP, функции WinAPI доступны в вариантах ANSI (A) и Unicode (W).См. Также В чем разница между функциями `A` и` W` в Win32 API? .

При использовании P / Invoke существует разница между C # и VB.NET.См. Указание набора символов в документах MS , в частности «Маршалинг строк и сопоставление имен» и «Указание набора символов в Visual Basic»:

Когда поле DllImportAttribute.ExactSpelling имеет значениеtrue, так как это по умолчанию в Visual Basic 2005, платформа вызывает поиск только по указанному вами имени.Например, если вы укажете MessageBox, платформа вызывает поиск MessageBox и завершается неудачно, когда не может найти точное написание.

Учитывая, что для поля DllImportAttribute.CharSet по умолчанию используется значение "ANSI" для C # и VB.NET, правила для Visual Basic определяют, что среда выполнения не ищет точку входа A или W , см. Документы: DllImportAttribute.ExactSpellingполе .Это для обратной совместимости с Visual Basic, я думаю.

Таким образом, у вас есть три варианта:

  1. Явно укажите точку входа "W" и CharSet.Unicode:

    <DllImport("shlwapi.dll", EntryPoint:="PathIsNetworkPathW", SetLastError:=True, CharSet:=CharSet.Unicode)> _
    Public Function PathIsNetworkPath(<MarshalAs(UnmanagedType.LPTStr)>pszPath As String) As <MarshalAs(UnmanagedType.Bool)>Boolean
    End Function
    
  2. Отключить точное написание, заставляя среду выполнения искать точку входа «A» (учитывая, что кодировка по умолчанию, если она не указана, - ANSI):

    <DllImport("shlwapi.dll", EntryPoint:="PathIsNetworkPath", SetLastError:=True, ExactSpelling:=False)> _
    Public Function PathIsNetworkPath(<MarshalAs(UnmanagedType.LPTStr)>pszPath As String) As <MarshalAs(UnmanagedType.Bool)>Boolean
    End Function
    
  3. Установите для CharSet значение Авто, что подразумевает набор символов для платформы (Unicode для большинства ОС) и ExactSpelling False:

    <DllImport("shlwapi.dll", EntryPoint:="PathIsNetworkPath", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Public Function PathIsNetworkPath(<MarshalAs(UnmanagedType.LPTStr)>pszPath As String) As <MarshalAs(UnmanagedType.Bool)>Boolean
    End Function
    

Я бы предпочел вариант 3, так как он исключает бесполезное (или даже опасное, так как это может привести к потере данных) Unicode -> ANSI -> Unicode преобразование строк и не требует явного указания "W""варианты функций.

...