.net 为什么这些DLL有两个明显相同的入口点?

.net 为什么这些DLL有两个明显相同的入口点?,.net,vb.net,dll,dllimport,.net,Vb.net,Dll,Dllimport,今天,在处理一些VB.NET代码时,为了使用一些方法,我不得不访问两个外部DLL。我找到的帮助主题告诉我使用以下外部方法: shlwapi.dll→ 路径网络路径() mpr.dll→ WNetAddConnection2和WNetCancelConnection2() 然而,当我试图从代码中调用这些方法时,我得到一个错误,即入口点不存在。因此,我做了一些研究,发现我的操作系统(Windows 7 enterprise 32位)中的DLL不完全包括这些方法,但我得到了: 路径是网络路径→

今天,在处理一些VB.NET代码时,为了使用一些方法,我不得不访问两个外部DLL。我找到的帮助主题告诉我使用以下外部方法:

  • shlwapi.dll→ 路径网络路径()
  • mpr.dll→ WNetAddConnection2和WNetCancelConnection2()
然而,当我试图从代码中调用这些方法时,我得到一个错误,即入口点不存在。因此,我做了一些研究,发现我的操作系统(Windows 7 enterprise 32位)中的DLL不完全包括这些方法,但我得到了:

  • 路径是网络路径→ PathIsNetworkPathA/PathIsNetworkPathW
  • wnetadconnection2→ WNetAddConnection2A/WNetAddConnection2W
  • WNetCancelConnection2→ WNetCancelConnection2A/WNetCancelConnection2W
因此,我测试了他们的行为: *方法按预期完成“A”工作。 *用“W”结束的方法不能按预期工作,它们会产生错误或返回错误的结果(g.i.“false”,当它应该是“true”时)。 然而,帮助主题中没有人提到有类似的问题

因此,我做了一些研究,发现DLL只包含以“a”和“W”结尾的方法,在我使用的三种情况下,就我所见,它们的文档页面是相同的。事实上,在整个页面中,他们不使用以a/W结尾的方法的名称,但不使用它


所以我的问题是:*为什么我的DLL中有“A”和“W”方法而不是没有A/W的方法?他们俩有什么不同?为什么方法“A”对我有效而方法“W”对我无效?

由于Windows NT 4/2000/XP,WinAPI函数有ANSI(A)和Unicode(W)两种变体。另见

使用p/Invoke时,C#和VB.NET之间存在差异。具体请参见“字符串封送和名称匹配”和“在Visual Basic中指定字符集”:

当DllImportAttribute.ExactSpelling字段为true时(在Visual Basic 2005中默认情况下),平台调用将仅搜索指定的名称。例如,如果指定MessageBox,platform invoke将搜索MessageBox,但在找不到确切拼写时失败

如果对于C#和VB.NET,DllImportAttribute.CharSet字段的默认值为“ANSI”,则Visual Basic的规则确定运行时不搜索AW入口点,请参阅。我想这是为了向后兼容Visual Basic

所以你有三个选择:

  • 显式指定“W”入口点和字符集。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
    
    _
    公共函数路径为布尔值的网络路径(pszPath为字符串)
    端函数
    
  • 禁用精确拼写,导致运行时搜索“A”入口点(如果未指定默认字符集,则为ANSI):

    _
    公共函数路径为布尔值的网络路径(pszPath为字符串)
    端函数
    
  • 将字符集设置为“自动”,这意味着拼写错误:

    <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
    
    _
    公共函数路径为布尔值的网络路径(pszPath为字符串)
    端函数
    

  • 我更喜欢选项3,因为它消除了字符串的Unicode->ANSI->Unicode的无用转换(甚至是危险的,因为它可能会导致数据丢失),并且不要求您明确指定函数的“W”变体。

    由于Windows NT 4/2000/XP,WinAPI函数有ANSI(A)和Unicode(W)变体。另见

    使用p/Invoke时,C#和VB.NET之间存在差异。具体请参见“字符串封送和名称匹配”和“在Visual Basic中指定字符集”:

    当DllImportAttribute.ExactSpelling字段为true时(在Visual Basic 2005中默认情况下),平台调用将仅搜索指定的名称。例如,如果指定MessageBox,platform invoke将搜索MessageBox,但在找不到确切拼写时失败

    如果对于C#和VB.NET,DllImportAttribute.CharSet字段的默认值为“ANSI”,则Visual Basic的规则确定运行时不搜索AW入口点,请参阅。我想这是为了向后兼容Visual Basic

    所以你有三个选择:

  • 显式指定“W”入口点和字符集。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
    
    _
    公共函数路径为布尔值的网络路径(pszPath为字符串)
    端函数
    
  • 禁用精确拼写,导致运行时搜索“A”入口点(如果未指定默认字符集,则为ANSI):

    _
    公共函数路径为布尔值的网络路径(pszPath为字符串)
    端函数
    
  • 将字符集设置为“自动”,这意味着拼写错误:

    <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
    
    _
    公共函数路径为布尔值的网络路径(pszPath为字符串)
    端函数
    

  • 我更喜欢选项3,因为它消除了字符串的Unicode->ANSI->Unicode转换的无用(甚至是危险的,因为它可能会导致数据丢失),并且不要求您明确指定函数的“W”变体。

    pinvoke marshaller已经知道这个细节。您在[DllImport]声明中使用的字符集属性很重要,CharSet.Ansi(默认)选择A版本,其他选择W。我们真正知道的是您的声明不正确,我们看不到它。我选择重新打开,因为问题更多的是关于事物的Visual Basic方面,而不仅仅是WinAPI函数的A和W变体之间的区别,@Damien。pinvoke marshaller已经知道这个细节。在[DllImport]声明中使用的字符集属性很重要,Char