Vb.net 如何找出非托管dll的正确参数结构?
我从VBA加载了一些旧的VB函数,大部分都更新到了VB.NET,但是“wininet.dll”中的函数声明似乎不匹配 我得到的错误是: 引发异常:托管调试助手“PinvokesTackDistancement”: 其长短不一之处在于声明参数的长度需要显式,并且与dll中的实际函数不匹配 我查了一下这个,只需删除检查就可以了,但它会有一个“堆栈不平衡”,最终会随着这些调用的进行耗尽所有堆栈。此外,这些被称为“非托管”DLL,一些声明已经放在位于的PInvoke函数wiki上。这个wiki确实有一些我正在使用的函数调用,但不是全部。其中的一些我不得不猜测一些事情,但没有成功 我从旧代码复制的大部分更改都是从Vb.net 如何找出非托管dll的正确参数结构?,vb.net,visual-studio,dll,vb6-migration,wininet,Vb.net,Visual Studio,Dll,Vb6 Migration,Wininet,我从VBA加载了一些旧的VB函数,大部分都更新到了VB.NET,但是“wininet.dll”中的函数声明似乎不匹配 我得到的错误是: 引发异常:托管调试助手“PinvokesTackDistancement”: 其长短不一之处在于声明参数的长度需要显式,并且与dll中的实际函数不匹配 我查了一下这个,只需删除检查就可以了,但它会有一个“堆栈不平衡”,最终会随着这些调用的进行耗尽所有堆栈。此外,这些被称为“非托管”DLL,一些声明已经放在位于的PInvoke函数wiki上。这个wiki确实有一些
long
更改为int32
或integer
,还有一些更改是IntPtr
,这在旧代码中从未使用过。我假设所有的整数大小都是正确的(即16/32/64位),这可能是大多数问题所在。但有一种情况是,从long
更改为string()
,这似乎有点奇怪,而且编译不正常
那么,如何在dll中查找函数长度并与API匹配呢?
我查了一些东西,但当我试图在Visual Studio中的VB.NET项目中添加对c:\windows\system32\wininet.dll的引用时,它说我无法添加它。这似乎阻止我在Visual Studio中使用对象或部件浏览器。它似乎不是COM对象。有人帮忙吗
以下是失败的旧代码供参考:
Private Declare Function InternetOpen Lib "wininet.dll" Alias "InternetOpenA" ( _
ByVal Agent As String, ByVal AccessType As Long, ByVal ProxyName As String, _
ByVal ProxyBypass As String, ByVal Flags As Long) As Long
Private Declare Function InternetConnect Lib "wininet.dll" Alias "InternetConnectA" ( _
ByVal hInternetSession As Long, ByVal ServerName As String, ByVal ServerPort As Integer, ByVal UserName As String, _
ByVal Password As String, ByVal Service As Long, ByVal Flags As Long, ByVal Context As Long) As Long
Private Declare Function InternetCloseHandle Lib "wininet.dll" ( _
ByVal hInet As Long) As Boolean
Private Declare Function InternetReadFile Lib "wininet.dll" ( _
ByVal hConnect As Long, ByVal Buffer As String, ByVal NumberOfBytesToRead As Long, _
NumberOfBytesRead As Long) As Boolean
Private Declare Function HttpOpenRequest Lib "wininet.dll" Alias "HttpOpenRequestA" ( _
ByVal hHttpSession As Long, ByVal Verb As String, ByVal ObjectName As String, ByVal Version As String, _
ByVal Referer As String, ByVal AcceptTypes As Long, ByVal Flags As Long, Context As Long) As Long
Private Declare Function HttpSendRequest Lib "wininet.dll" Alias "HttpSendRequestA" ( _
ByVal hHttpRequest As Long, ByVal Headers As String, ByVal HeadersLength As Long, _
ByVal sOptional As String, ByVal OptionalLength As Long) As Boolean
您应该使用托管替代方案
然而,为了回答您的实际问题:您基本上只需要查看MSDN文档文章,并根据类型的声明确定相应的.NET类型
例如,DWORD
:
DWORD32位无符号整数。范围为0到4294967295十进制 此类型在IntSafe.h中声明如下:
typedef无符号长DWORD代码>
在这种情况下,我们可以通过范围(0-4294967295)或定义(无符号长
)来确定这应该是一个无符号32位整数(UInt32
或UInteger
)。在C/C++中,long
与int
是一样的,这就是为什么它被映射到整数而不是long/ULong
以下是最常见类型的摘要:
(非常感谢您帮助我更正了一些字符串声明!)
+------------------+------------------------------------------------------+
|Windows类型|.NET等效|
+------------------+------------------------------------------------------+
|布尔值(vb.net)|
|BOOL |[Marshallas(UnmanagedType.BOOL)]BOOL(c#)|
|字节|字节/字节(vb.net)/字节(c#)|
|CHAR | CHAR/CHAR(vb.net)/CHAR(c#)|
|DWORD | UInt32/UInteger(vb.net)/uint(c#)|
|DWORDLONG | UInt64/ULong(vb.net)/ULong(c#)|
|德沃德·乌普特|
|FLOAT | Single/Single(vb.net)/FLOAT(c#)|
| | |
|手柄| IntPtr|
|HBITMAP | IntPtr|
|HCURSOR | IntPtr|
|HDESK | IntPtr|
|HDC | IntPtr|
|HICON | IntPtr|
|HINSTANCE | IntPtr|
|HRESULT | Int32/Integer(vb.net)/int(c#)|
|HWND | IntPtr|
| | |
|INT | Int32/Integer(vb.net)/INT(c#)|
|INT|PTR | IntPtr|
|INT8 | SByte|
|INT16 | INT16/Short(vb.net)/Short(c#)|
|INT32 | INT32/Integer(vb.net)/int(c#)|
|INT64 | INT64/Long(vb.net)/Long(c#)|
|LONG | Int32/Integer(vb.net)/int(c#)|
|LONGLONG | Int64/Long(vb.net)/Long(c#)|
|LONG_PTR | IntPtr|
|LPARAM | IntPtr|
| | |
|LPCSTR |字符串(在DllImport中指定CharSet.Ansi)|
|LPCTSTR |字符串|
|LPCWSTR |字符串(在DllImport中指定CharSet.Unicode)|
|LPDWORD |(=DWORD,声明为ByRef(vb.net)/ref(c#))|
|LPHANDLE |(=HANDLE,声明为ByRef(vb.net)/ref(c#))|
|LPINT | IntPtr|
|LPLONG | IntPtr|
|