VBAでOLE32.DLLを使う場合の質問です。 https://snipplr.com/view/37940 上記のサイトをコピペさせてもらい、以下のコードでUUIDを生成しています。
VBAでOLE32.DLLを使う場合の質問です。 https://snipplr.com/view/37940 上記のサイトをコピペさせてもらい、以下のコードでUUIDを生成しています。 Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(7) As Byte End Type Private Declare Function CoCreateGuid Lib "OLE32.DLL" (pGuid As GUID) As Long Public Function GetGUID() As String '(c) 2000 Gus Molina Dim udtGUID As GUID If (CoCreateGuid(udtGUID) = 0) Then GetGUID = _ String(8 - Len(Hex$(udtGUID.Data1)), "0") & Hex$(udtGUID.Data1) & "-" & _ String(4 - Len(Hex$(udtGUID.Data2)), "0") & Hex$(udtGUID.Data2) & "-" & _ String(4 - Len(Hex$(udtGUID.Data3)), "0") & Hex$(udtGUID.Data3) & "-" & _ IIf((udtGUID.Data4(0) < &H10), "0", "") & Hex$(udtGUID.Data4(0)) & _ IIf((udtGUID.Data4(1) < &H10), "0", "") & Hex$(udtGUID.Data4(1)) & "-" & _ IIf((udtGUID.Data4(2) < &H10), "0", "") & Hex$(udtGUID.Data4(2)) & _ IIf((udtGUID.Data4(3) < &H10), "0", "") & Hex$(udtGUID.Data4(3)) & _ IIf((udtGUID.Data4(4) < &H10), "0", "") & Hex$(udtGUID.Data4(4)) & _ IIf((udtGUID.Data4(5) < &H10), "0", "") & Hex$(udtGUID.Data4(5)) & _ IIf((udtGUID.Data4(6) < &H10), "0", "") & Hex$(udtGUID.Data4(6)) & _ IIf((udtGUID.Data4(7) < &H10), "0", "") & Hex$(udtGUID.Data4(7)) End If End Function この場合64ビットのオフィスで使用すると。PtrSafeをつけろと怒られるので、 Private Declare PtrSafe Function CoCreateGuid Lib "OLE32.DLL" (pGuid As GUID) As Long 上記のように書き換えてうまく動いています。 なんで動くのかよくわからなっかので、勉強の為に調べたらどうやら32bitと64bit のofficeで使うメモリの型の違いで、64bitのofficeで使う場合に想定していない番地にデーターを書き込もうとする為に、officeがクラッシュするという事が何となくわかりました。 質問ですが、この考え方はあっているでしょうか? だとした場合、上記のコードでも同じ危険性があるかどうかと、対策方法を教えてもらうと助かります。32bitと64bit両方で使わなければなりません。 よろしくお願いいたします。
Visual Basic・99閲覧・500
ベストアンサー
Win32 API の関数自体の入出力は 32bit のみで行われますので、64bit版 Office では 64bit - 32bit 間の情報量の変換を行いながら Win32API と通信します。そのフラグとなるキーワードが PtrSafe です。 【CoCreateGuid 関数について】 ご質問のコードは CoCreateGuid 関数を使っていますが、プロトタイプは C++ で HRESULT CoCreateGuid( [out] GUID *pguid ); となっています。 https://docs.microsoft.com/ja-jp/windows/win32/api/combaseapi/nf-combaseapi-cocreateguid この関数の戻り値の HRESULT ですが 32bit 値である事が以下のリンクで判断できます。 https://docs.microsoft.com/ja-jp/office/client-developer/outlook/mapi/hresult そのため、Declare ステートメントでの戻り値の部分は、厳密には Long ではなく LongPtr となります。ですが、プロシージャ内では S_OK を示す 0 しか使われていないので、Long でも正常動作すると思います。 https://docs.microsoft.com/ja-jp/windows/win32/seccrypto/common-hresult-values 【32bitと64bit両方で使うための対策】 条件付きコンパイル方式を使って記述します。(#If Win64 Then は、Office が 64bit版かどうかを判断するものです) 64bit版の Office の場合、32bit側の記述が赤くなります。逆に 32bit版の Office の場合、64bit側の記述が赤くなります。これはコンパイルできない箇所を示していて、記述そのものは合っています。 ' ------------ 以下 対策コード ----------- ' Excel2007 (32bit only) での動作確認なので 64bit では未確認です。 Private Type GUID Data1 As Long Data2 As Integer Data3 As Integer Data4(7) As Byte End Type #If Win64 Then Private Declare PtrSafe Function CoCreateGuid Lib "OLE32.DLL" ( _ pGuid As GUID _ ) As LongPtr #Else Private Declare Function CoCreateGuid Lib "OLE32.DLL" ( _ pGuid As GUID _ ) As Long #End If Public Function GetGUID() As String Dim udtGUID As GUID If (CoCreateGuid(udtGUID) = 0) Then GetGUID = _ String(8 - Len(Hex$(udtGUID.Data1)), "0") & Hex$(udtGUID.Data1) & "-" & _ String(4 - Len(Hex$(udtGUID.Data2)), "0") & Hex$(udtGUID.Data2) & "-" & _ String(4 - Len(Hex$(udtGUID.Data3)), "0") & Hex$(udtGUID.Data3) & "-" & _ IIf((udtGUID.Data4(0) < &H10), "0", "") & Hex$(udtGUID.Data4(0)) & _ IIf((udtGUID.Data4(1) < &H10), "0", "") & Hex$(udtGUID.Data4(1)) & "-" & _ IIf((udtGUID.Data4(2) < &H10), "0", "") & Hex$(udtGUID.Data4(2)) & _ IIf((udtGUID.Data4(3) < &H10), "0", "") & Hex$(udtGUID.Data4(3)) & _ IIf((udtGUID.Data4(4) < &H10), "0", "") & Hex$(udtGUID.Data4(4)) & _ IIf((udtGUID.Data4(5) < &H10), "0", "") & Hex$(udtGUID.Data4(5)) & _ IIf((udtGUID.Data4(6) < &H10), "0", "") & Hex$(udtGUID.Data4(6)) & _ IIf((udtGUID.Data4(7) < &H10), "0", "") & Hex$(udtGUID.Data4(7)) End If End Function
質問者からのお礼コメント
早いアンサーで助かります。 コードはしっかり動きました。 教えて頂いたサイトをしっかりと読んで勉強しようと思います。 本当にありがとうございました。
お礼日時:1/17 11:49