none
64bit環境下におけるAPI宣言とLongPtr RRS feed

  • 質問

  • さっそくですが、64bit環境下でのAPI宣言として、以下の(A)と(B)の記述はどちらが正しいでしょうか?

    (A) Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As Long)
    (B) Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal ms As LongPtr)

    ネット上で検索すると、圧倒的に(B)の提示例が多いのですが、LongPtr型は「ポインタ及びハンドルを代入する変数」に指定するものではないかと思っています。

    つまり、(A)が正解ではないかと思うのですが違いますか?

    また、他APIを利用する場合など、宣言が合っているかどうかを確かめる方法として、どのような方法がありますか?

    2018年10月26日 0:33

回答

  • 下記から PtrSafe を記述した API 定義の一覧をダウンロードできます。

    ダウンロードした EXEファイルを実行すると、Win32API_PtrSafe Download URL.txt という

    テキストファイルがインストールされます。その中に PtrSafe付きのAPI 定義が沢山収録されています。

     

    Office 2010 Help Files: Win32API_PtrSafe with 64-bit Support

    https://www.microsoft.com/en-us/download/details.aspx?id=9970

    このテキストの記述では下記のように記載されています。

    Declare PtrSafe Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)

     

    Win32API_PtrSafe Download URL.txt をブラウザの「お気に入り」に入れておいて、ブラウザで閲覧すると検索なども楽ですよ。

    2018年10月26日 2:56
  • はい (A) が正しいと思います。

    Sleep 関数のドキュメントを見ますと、引数はポインタやハンドルではなく DWORD (4バイト) 整数値となっていますので、(A)でよいかと思います。

    参考サイト: https://msdn.microsoft.com/ja-jp/library/cc429358.aspx

    • 回答としてマーク minmin312 2018年10月26日 17:55
    2018年10月26日 0:51
  • 結論が変わるわけではありませんが、kenjinoteさんが参照されたドキュメントはWindowsが64bit対応する前の古いドキュメントです。64bit環境についての議論で参照するのは不適切です。正しくはhttps://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-sleepを参照すべきです。

    また蛇足ですが、第1引数はどのみちRCXレジスタに格納されるため64bitデータ型となっています。正しくはLongと書くべきですが、LongPtrと書かれていても問題なく動作します。

    • 回答としてマーク minmin312 2018年10月27日 5:22
    2018年10月26日 21:10
  • 誤解されています。

    まず当該記事はVisual C++に対するもので、具体的な言語としてはC言語及びC++言語に関するものとなります。そしてkernel32.dllを含むWindows APIはVisual C++を使用してC言語またはC++言語を使用して作成されているため、全てのWindows APIにもこの仕様が適用されます。

    その上で、VBAのDeclare構文でもVB.NETのDeclare構文でも、DLLであるWindows APIを呼び出す機能です。ですので、Declare構文についても当該記事の仕様が適用されます。

    • 回答としてマーク minmin312 2018年10月28日 17:00
    2018年10月27日 9:50

すべての返信

  • はい (A) が正しいと思います。

    Sleep 関数のドキュメントを見ますと、引数はポインタやハンドルではなく DWORD (4バイト) 整数値となっていますので、(A)でよいかと思います。

    参考サイト: https://msdn.microsoft.com/ja-jp/library/cc429358.aspx

    • 回答としてマーク minmin312 2018年10月26日 17:55
    2018年10月26日 0:51
  • 下記から PtrSafe を記述した API 定義の一覧をダウンロードできます。

    ダウンロードした EXEファイルを実行すると、Win32API_PtrSafe Download URL.txt という

    テキストファイルがインストールされます。その中に PtrSafe付きのAPI 定義が沢山収録されています。

     

    Office 2010 Help Files: Win32API_PtrSafe with 64-bit Support

    https://www.microsoft.com/en-us/download/details.aspx?id=9970

    このテキストの記述では下記のように記載されています。

    Declare PtrSafe Sub Sleep Lib "kernel32" Alias "Sleep" (ByVal dwMilliseconds As Long)

     

    Win32API_PtrSafe Download URL.txt をブラウザの「お気に入り」に入れておいて、ブラウザで閲覧すると検索なども楽ですよ。

    2018年10月26日 2:56
  • お二方ともありがとうございました。大変参考になりました。
    2018年10月26日 17:55
  • 結論が変わるわけではありませんが、kenjinoteさんが参照されたドキュメントはWindowsが64bit対応する前の古いドキュメントです。64bit環境についての議論で参照するのは不適切です。正しくはhttps://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-sleepを参照すべきです。

    また蛇足ですが、第1引数はどのみちRCXレジスタに格納されるため64bitデータ型となっています。正しくはLongと書くべきですが、LongPtrと書かれていても問題なく動作します。

    • 回答としてマーク minmin312 2018年10月27日 5:22
    2018年10月26日 21:10
  • > 第1引数はどのみちRCXレジスタに格納されるため64bitデータ型となっています。

    有益な情報ありがとうございます。

    ただ、リンク先の記事は、Visual Studio 2015 に関するものと思うのですが、これはAPI呼び出しおよびVBAにも当てはまるのでしょうか?

    2018年10月27日 5:33
  • もちろんです。呼び出されるSleepが含まれているkernel32.dll側の仕様ですから、呼び出し言語には依存しません。
    2018年10月27日 6:23
  • 私の理解力が足りずしつこくなってしまい申し訳ないのですが、当該記事は、「.Net Framework」環境下での関数パラメータの取り扱い仕様(Any CPUでコンパイルした場合など)ついて書かれているのではないのでしょうか?

    「kernel32.dll」は「API」であり、「API」と「.Net Framework」は別物と思いますが、私の認識不足でしょうか?

    2018年10月27日 7:26
  • 誤解されています。

    まず当該記事はVisual C++に対するもので、具体的な言語としてはC言語及びC++言語に関するものとなります。そしてkernel32.dllを含むWindows APIはVisual C++を使用してC言語またはC++言語を使用して作成されているため、全てのWindows APIにもこの仕様が適用されます。

    その上で、VBAのDeclare構文でもVB.NETのDeclare構文でも、DLLであるWindows APIを呼び出す機能です。ですので、Declare構文についても当該記事の仕様が適用されます。

    • 回答としてマーク minmin312 2018年10月28日 17:00
    2018年10月27日 9:50
  • 詳細にご説明頂き、ありがとうございました。

    お陰様で何とか得心いたしました。

    2018年10月28日 17:00