tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル Re^7: VB2010 internetsetoption
投稿日: 2015/04/17(Fri) 10:50
投稿者魔界の仮面弁士
>    Private Declare Function InternetOpen Lib "wininet.dll" Alias _
>        "InternetOpenA" (ByVal sAgent As String, ByVal lAccessType As Integer, _
>         ByVal sProxyName As String, ByVal sProxyBypass As String, _
>         ByVal lFlags As Integer) As Integer

Win9x 系が淘汰された現在では、あえて A系を選択する必要性は薄いと思います。
VBA なら Ansi Function の方が楽ですが、.NET なら Unicode Function の方が良いですよ。


>   Private Declare Auto Function InternetSetOption Lib "wininet.dll" _
>        (ByVal hInternet As Integer, ByVal dwOption As Integer, _
>         ByVal lpBuffer As Integer, ByVal lpdwBufferLength As Integer) As Boolean

以下一般論。

 h で始まる引数名は、ハンドル型の引数を意味します。
  → 一般的には、ByVal IntPtr とします。なお、対象オブジェクトによっては、
    さらにカプセル化したクラスが使われることもあります。
    (例:Microsoft.Win32.SafeHandles 名前空間)

 dw で始まる引数名は、DWORD 型の引数を意味します。
  → 本来の型は ByVal UInteger です。ただし ByVal Integer もよく使われます。

 lp で始まる引数名は、LONG POINTER な引数を意味します。
  → 「ByRef 値型」「ByVal 参照型」「ByVal IntPtr」などが使われます。
    LPRECT なら ByRef RECT構造体、などのように。
    LPVOID の場合、複数のデータ型が渡される可能性があるため、
    VB.NET ではオーバーロードで対応することが多いです。

上記を踏まえたうえで、元の API 定義を見てみると
https://msdn.microsoft.com/en-us/library/windows/desktop/aa385114/
となっています。


まず第 4 引数。ここには第 3 引数のデータ長(文字数またはバイト数)が入ります。
データ型は DWORD 。なので、ByVal dwBufferLength As Integer/UInteger が適切です。

しかし提示された宣言は、ByVal lpdwBufferLength As Integer になっていますよね。
引数名が動作に影響を与えるわけではありませんが、lpdw の接頭辞だと、
ByRef UInteger を連想してしまいます。(定義としては間違っていないのですが)


次に第 3 引数。ここには第 2 引数に指定したオプション値によって
異なる値が渡されるわけですが、今回のタイムアウト設定の場合は、
DWORD のポインタが渡されることになります。
つまり、★ByVal Integer にするのは誤り★で、
ByRef UInteger/Integer にするべきでしょう。
ByVal IntPtr でも間違いでは無いですが、それが冗長なことは先述の通り。


第 2 引数。ここは ByVal UInteger / Integer なので問題なし。
オプション定数群を Enum にして、ByVal 列挙型としてみるのも良いですね。


第 1 引数。ByVal Integer は正しくありません。
x86 ビルドの場合は限定的に利用可能ではありますが、本来は ByVal IntPtr です。


戻り値。これは As Boolean のままで OK です。より明確にするために、
As <MarshalAs(UnmanagedType.Bool)> Boolean と書くこともあります。



…というか、今まで VB6 では動いていたんですよね。その時は、それぞれの引数を
どのように定義し、そこにどんな型の変数を渡していたのでしょうか? (特に第3引数)


> Public Const INTERNET_OPTION_CONNECT_TIMEOUT As Integer = 2 '接続タイムアウト
こっちは「As」付きで、
> Private Const USER_AGENT = "WININET"            'ユーザーエージェント名
こっちは「As」なしなのが気にかかります。まぁ良いですけど。


> Private hOpen As Integer                        ' オープンハンドル
> Private hConnect As Integer                     ' コネクトハンドル
ハンドルは IntPtr で統一しましょう。


>       dim timeout as integer
……小文字? ここは実際のコードとは違うのですね。


> timeoutの値を1000にするとInternetSetOptionはFalseを返し、
> 99999にするとTrueを返します。
ByVal / ByRef の時点で間違っていましたので、その動作はおそらく偶然です。
パソコンを何度か再起動すると、また違う動作になってしまう可能性すらあるでしょう。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。