问题
I'm trying to convert this VB.NET / C# declaration into a Visual Basic 6.0 one, having trouble (included is the C# version, converting to VB.NET not a problem):
[DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
private static extern int UrlMkSetSessionOption(
int dwOption,
string pBuffer,
int dwBufferLength,
int dwReserved);
As you can see, in Visual Basic/C# we have that CharSet=CharSet.Ansi
part, which I don't know how to do in Visual Basic 6.0 - I tried adding the A at the end of the Alias Name... Alias "UrlMkSetSessionOptionA"
... but that didn't work (says can't find DLL entrypoint in urlmon.dll
). Without this, the string sent to pBuffer is coming out as gibberish (weird characters I can't recognize).
Here is what I've gotten so far...
Public Declare Sub UrlMkSetSessionOption Lib "urlmon.dll" (ByVal _
dwOption As Long, _
pBuffer As Any, _
ByVal dwBufferLength As Long, _
ByVal dwReserved As Long)
回答1:
You declare the VB6 function as Sub
, making the compiler/interpreter look for a void
function (also known as procedure), while the actual function has an int
return type.
It should work if you change your include statement to this:
Public Declare Function UrlMkSetSessionOption Lib "urlmon.dll" (ByVal _
dwOption As Long, _
pBuffer As Any, _
ByVal dwBufferLength As Long, _
ByVal dwReserved As Long) As Long
It may be that you'll also have to replace all occurences of Long
with Integer
, but due to my lack of experience with VB6 I'm not sure.
回答2:
I've just figured out that the declaration is correct, and there was a particular way that it needed to be called - basically you need to pass the string as ByVal - it just randomly worked while I was trying a combination of different things. Thank you for everyone for their contribution. Here is the call if declared as a sub.
UrlMkSetSessionOption URLMON_OPTION_USERAGENT, ByVal strUA, Len(strUA), 0
I hope this is useful to someone - when you call the second argument without the "ByVal strUA" and just pass "strUA" the internal function must assume ByRef, which means it is trying to use the variable we passed it (an ANSI Visual Basic 6.0 STRING), and of course, when it does this, it ends up as gibberish as the string type the C function uses is not an ANSI Visual Basic string type.
So, when passing it as ByVal it just passes it by value (not by reference) and can then use its own variable/datatype combination which is compatible with the string type it uses. I hope that helps someone.
回答3:
Const URLMON_OPTION_USERAGENT = &H10000001
Const URLMON_OPTION_USERAGENT_REFRESH = &H10000002
Private Declare Function UrlMkSetSessionOption Lib "urlmon" (ByVal dwOption As Long, ByVal pBuffer As String, ByVal dwBufferLength As Long, ByVal dwReserved As Long) As Integer
Public Function ChangeUserAgent
(Optional ByVal MyUserAgent As String = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36")
Call UrlMkSetSessionOption(URLMON_OPTION_USERAGENT_REFRESH, vbNullString, 0, 0)
Call UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, MyUserAgent, LenB(MyUserAgent), 0)
End Function
来源:https://stackoverflow.com/questions/9047721/how-to-do-public-declare-ansi-function-in-visual-basic-6-0