今天,在处理某些VB.NET代码时,我必须访问两个外部DLL才能使用某些方法。我发现的帮助主题告诉我使用以下外部方法:
但是,当我尝试从代码中调用这些方法时,出现一个错误,指出该入口点不存在。因此,我进行了一些研究,发现操作系统中的DLL(Windows 7企业版32位)没有完全包含这些方法,而是得到了:
因此,我测试了他们的行为: *以“ A”结尾的方法按预期工作。 *以“ W”结尾的方法不能按预期方式工作,它们会引发错误或返回错误的结果(例如,应为“ true”的情况下为“ false”)。 但是,在帮助主题中,没有人提到存在类似问题。
因此,我做了一些研究,在MSDN documentation中,我发现DLL仅包含以“ A”和“ W”结尾的方法,并且在这三个方法中,就我使用的案例而言,据我所知,文档页面完全相同。实际上,在整个页面中,他们都不使用以A / W结尾但没有A / W的方法的名称。
所以我的问题是:*为什么我的DLL中有方法“ A”和“ W”,而不是没有A / W的方法?两者有什么区别?为什么方法“ A”对我有效而方法“ W”对我无效?
答案 0 :(得分:4)
自Windows NT 4/2000 / XP起,WinAPI函数具有ANSI(A)和Unicode(W)变体。另请参见What is the difference between the `A` and `W` functions in the Win32 API?。
使用P / Invoke时,C#和VB.NET之间存在区别。请参见Specifying a Character Set on MS Docs,尤其是“字符串封送和名称匹配”和“在Visual Basic中指定字符集”:
当DllImportAttribute.ExactSpelling字段为true时(在Visual Basic 2005中默认情况下),平台调用仅搜索您指定的名称。例如,如果指定MessageBox,则平台调用会搜索MessageBox并在找不到精确的拼写时失败。
鉴于C#和VB.NET的DllImportAttribute.CharSet字段的默认值为“ ANSI”,Visual Basic的规则确定运行时不搜索 A < / strong>或 W 入口点,请参见Docs: DllImportAttribute.ExactSpelling Field。我猜这是为了与Visual Basic向后兼容。
因此,您有三个选择:
明确指定“ 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
禁用精确拼写,导致运行时搜索“ 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
将CharSet设置为Auto,这意味着platform-specific character set (Unicode for most OSes)并且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”函数的变体。