воскресенье, 18 марта 2012 г.

Ошибка: The code in this project must be updated for use on 64-bit systems

В приложениях Visual Basic for Application в Microsoft Office 2010 может возникнуть следующая ошибка:

Compile error:
The code in this project must be updated for use on 64-bit systems.
Please review and update Declare statements and then mark them with the PtrSafe attribute.


Проблема известная, описана в базе знаний Microsoft как KB983043. Решается добавлением слова  PtrSafe после слова Declare. Для примера на рисунке было:
Private Declare Function URLDownloadToFile...
стало
Private Declare PtrSafe Function URLDownloadToFile...

Но согласно заметке http://msdn.microsoft.com/en-us/library/gg251723.aspx:
Adding the PtrSafe keyword to a Declare statement only signifies the Declare statement explicitly targets 64-bits, all data types within the statement that need to store 64-bits (including return values and parameters) must still be modified to hold 64-bit quantities using either LongLong for 64-bit integrals or LongPtr for pointers and handles.
потребуется изменение типов: LongLong для хранения любых целых чисел (но в 64-битовом представлении), и LongPtr для указателей и дескрипторов. Теперь заголовок функции выглядит так:
Private Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" ( _
 ByVal pCaller As LongLong, _
 ByVal szURL As String, _
 ByVal szFileName As String, _
 ByVal dwReserved As LongLong, _
 ByVal lpfnCB As LongLong) As LongLong

Чтобы избежать переделки кода на различных системах, правильно будет написать:
#If Win64 Then
 Private Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" ( _
  ByVal pCaller As LongLong, _
  ByVal szURL As String, _
  ByVal szFileName As String, _
  ByVal dwReserved As LongLong, _
  ByVal lpfnCB As LongLong) As LongLong
#Else
Private Declare PtrSafe Function URLDownloadToFile Lib "urlmon" Alias "URLDownloadToFileA" ( _
 ByVal pCaller As Long, _
 ByVal szURL As String, _
 ByVal szFileName As String, _
 ByVal dwReserved As Long, _
 ByVal lpfnCB As Long) As Long
#End If

Рекомендую также прочитать http://msdn.microsoft.com/en-us/library/ee691831.aspx.

1 комментарий: