- ベストアンサー
ExcelVBAでのkernel32(64bit)に関する問題と解決方法
- ExcelVBAでC++で作ったプログラムを動かす際にWindows7上のExcel2010でエラーメッセージが表示される場合、DeclareにPtrSafeを付ける必要があります。ただし、他のコードはそのままで問題ありません。
- 32bitの場合はDeclareの関数宣言はそのまま使用して問題ありません。
- Win32 API関数・定数の宣言について、コード中のLongには変更の必要はありません。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
LongPtrの補足ですが、 32bit環境で動かした場合は、LongPtrは32bit、 64bit環境で動かした場合は、LongPtrは64bitとして扱われます。 上記の通りポインタは大きさが変わる物で、他言語ではある程度流動的に変わる仕様なのですが、 VB(VBA)の整数型(int, long)は常に大きさが変わらない仕様であったため、 今回のような事になったのでしょう。 >> OpenProcessの戻り値もアドレスなのでLongPtrにする必要がある はい、そうです。 >> 1. かつてのVBAではポインタ(32bit)を扱う型が無かったので、同じ32bitであるLongで代用していた。 >> 2. 64bit環境ではアドレスが64bitになるので、32bitのLongに格納するとデータが欠落する。 >> 3. これの対策としてポインタとしてのLongPtrという型が追加された。 >> 4. 今回のプログラムの場合、OpenProcessがプロセスハンドルとしてアドレスを返す。 はい、そうです。 >> 5. これを受け取るデータ型はVariantなので問題ないが(自動で判別するから?)、 >> WaitForSingleObjectの第1引数及びCloseHandleには64bitのポインタを渡す必要がある。 Variantで問題があるかどうかは分かりませんが、 OpenProcess関数はHANDLE型を返しますので、受け側(h_proc)はLongPtrが適切だと思います。 >> 6. 結果、WaitForSingleObjectの第1引数とCloseHandleの引数をLongPtrにする必要がある。 はい、そうです。
その他の回答 (2)
- kumatti1
- ベストアンサー率60% (73/121)
こんにちは。 APIの宣言自体は、Win32API_PtrSafe.TXTから持って来ればいいです。 http://www.microsoft.com/download/en/details.aspx?id=9970 C:\Office 2010 Developer Resources\Documents\Office2010Win32API_PtrSafe\Win32API_PtrSafe.TXT # それと、コード中のおかしな所は、直しました。 Public Sub Run(ByVal project_name As String) Dim program As String Dim task_id As Long Dim h_proc As LongPtr program = mdlFunc.ProgramPath() & mdlFunc.ProgramOption(project_name) 'プログラム名 task_id = Shell(program, vbHide) h_proc = OpenProcess(PROCESS_ALL_ACCESS, 1, task_id) If h_proc <> 0 Then Call WaitForSingleObject(h_proc, INFINITE) CloseHandle h_proc End If End Sub
お礼
ご回答いただきましてありがとうございます。ご紹介いただきましたtxtデータを見てみました。少しずつ勉強してみます。
- duke_kimura
- ベストアンサー率39% (53/134)
ざっと見ておかしいのは、(*)のLongです。 64bit環境になってからは、これをLongPtrにする必要があるかと。 Declare PtrSafe Function WaitForSingleObject Lib "kernel32"( ByVal hHandle As Long(*), ByVal dwMilliseconds As Long) As Long dwMilliseconds側のLongはそのままです。 他も同様に、数値の値としてのLongはそのままで、ポインタやハンドルとしてのLongはLongPtrにしてみてください。
お礼
ご回答いただきありがとうございます。いまいち正しく理解できているか判らないので確認させてください。 1. かつてのVBAではポインタ(32bit)を扱う型が無かったので、同じ32bitであるLongで代用していた。 2. 64bit環境ではアドレスが64bitになるので、32bitのLongに格納するとデータが欠落する。 3. これの対策としてポインタとしてのLongPtrという型が追加された。 4. 今回のプログラムの場合、OpenProcessがプロセスハンドルとしてアドレスを返す。 5. これを受け取るデータ型はVariantなので問題ないが(自動で判別するから?)、WaitForSingleObjectの第1引数及びCloseHandleには64bitのポインタを渡す必要がある。 6. 結果、WaitForSingleObjectの第1引数とCloseHandleの引数をLongPtrにする必要がある。 以上で間違いないでしょうか。お時間があれば確認していただけると幸いです。よろしくお願いいたします。
補足
追加ですみません。OpenProcessの戻り値もアドレスなのでLongPtrにする必要がある、という理解で間違いないでしょうか。
お礼
丁寧にお教えいただきありがとうございました。詳細なことはこれから勉強しようと思いますが、今回のポインタの件は何となく理解できたような気がします。