• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ExcelVBAでのkernel32(64bit))

ExcelVBAでのkernel32(64bit)に関する問題と解決方法

このQ&Aのポイント
  • ExcelVBAでC++で作ったプログラムを動かす際にWindows7上のExcel2010でエラーメッセージが表示される場合、DeclareにPtrSafeを付ける必要があります。ただし、他のコードはそのままで問題ありません。
  • 32bitの場合はDeclareの関数宣言はそのまま使用して問題ありません。
  • Win32 API関数・定数の宣言について、コード中のLongには変更の必要はありません。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.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にする必要がある。 はい、そうです。

参考URL:
http://msdn.microsoft.com/ja-jp/library/ee691831.aspx
kary
質問者

お礼

丁寧にお教えいただきありがとうございました。詳細なことはこれから勉強しようと思いますが、今回のポインタの件は何となく理解できたような気がします。

その他の回答 (2)

  • kumatti1
  • ベストアンサー率60% (73/121)
回答No.2

こんにちは。 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

kary
質問者

お礼

ご回答いただきましてありがとうございます。ご紹介いただきましたtxtデータを見てみました。少しずつ勉強してみます。

回答No.1

ざっと見ておかしいのは、(*)のLongです。 64bit環境になってからは、これをLongPtrにする必要があるかと。 Declare PtrSafe Function WaitForSingleObject Lib "kernel32"(  ByVal hHandle As Long(*),  ByVal dwMilliseconds As Long) As Long dwMilliseconds側のLongはそのままです。 他も同様に、数値の値としてのLongはそのままで、ポインタやハンドルとしてのLongはLongPtrにしてみてください。

kary
質問者

お礼

ご回答いただきありがとうございます。いまいち正しく理解できているか判らないので確認させてください。 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にする必要がある。 以上で間違いないでしょうか。お時間があれば確認していただけると幸いです。よろしくお願いいたします。

kary
質問者

補足

追加ですみません。OpenProcessの戻り値もアドレスなのでLongPtrにする必要がある、という理解で間違いないでしょうか。

関連するQ&A

専門家に質問してみよう