2012-01-12 42 views
5

在Delphi XE2 Win32平臺中運行以下代碼。然而,同樣的代碼在Win64的平臺編譯會導致訪問衝突「EnumRCDataProc」如果在調試模式:Delphi XE2:調用WinAPI EnumResourceNames在Win64平臺中導致訪問衝突

procedure TForm2.Button1Click(Sender: TObject); 
    function EnumRCDataProc(hModule: THandle; lpszType, lpszName: PChar; lParam: 
     NativeInt): Boolean; stdcall; 
    begin 
    TStrings(lParam).Add(lpszName); 
    Result := True; 
    end; 

var k: NativeInt; 
    L: TStringList; 
    H: THandle; 
begin 
    H := LoadPackage('resource.bpl'); 
    L := TStringList.Create; 
    try 
    EnumResourceNames(H, RT_RCDATA, @EnumRCDataProc, NativeInt(L)); 
    ShowMessage(L.Text); 
    finally 
    L.Free; 
    UnloadPackage(H); 
    end; 
end; 

當調試Win64上平臺在Delphi XE2 IDE的代碼,我發現HMODULE的值EnumRCDataProc與變量H不匹配。我懷疑這可能是我爲EnumRCDataProc構造的參數錯誤的。但是,我無法弄清楚如何。有任何想法嗎?

回答

5

問題是您已將EnumRCDataProc作爲本地過程。你需要將它移到方法之外。

function EnumRCDataProc(hModule: HMODULE; lpszType, lpszName: PChar; lParam: 
    NativeInt): BOOL; stdcall; 
begin 
    TStrings(lParam).Add(lpszName); 
    Result := True; 
end; 

procedure TForm2.Button1Click(Sender: TObject); 
var k: NativeInt; 
    L: TStringList; 
    H: HMODULE; 
begin 
    H := LoadPackage('resource.bpl'); 
    L := TStringList.Create; 
    try 
    EnumResourceNames(H, RT_RCDATA, @EnumRCDataProc, NativeInt(L)); 
    ShowMessage(L.Text); 
    finally 
    L.Free; 
    UnloadPackage(H); 
    end; 
end; 

乍一看我預計,編譯器會發出錯誤與您的代碼:

E2094局部過程/函數「回調」分配給程序變量

但它確實不這樣做。我挖得更深一點,發現EnumResourceNames的回調參數被聲明爲Pointer。如果標題翻譯已經將其聲明爲一個類型化的回調參數,那麼上面的錯誤信息確實會被髮出。在我看來,標題翻譯在這方面很差。放棄類型系統的安全似乎很少能獲得。

您的代碼在32位代碼中工作的事實只是一個依賴實現細節的巧合。你的運氣用完了64位。同樣,如果類型檢查系統已經啓用,編譯器可以立即告訴你什麼是錯誤的。

一些其他意見:

  1. EnumRCDataProc有幾個不正確類型的聲明:hModule應該HMODULE類型和功能的結果應該是BOOL
  2. LoadPackage是一個相當重量級的獲取模塊句柄的方法。我希望看到LoadLibraryExLOAD_LIBRARY_AS_DATAFILE_EXCLUSIVELOAD_LIBRARY_AS_IMAGE_RESOURCE選項。
+0

編譯器不應該抱怨。本地枚舉函數根本不是問題。 – OnTheFly 2012-01-12 15:46:47

+0

猜測,它爲什麼會發出:p – OnTheFly 2012-01-12 17:05:10

+1

只要回調沒有訪問任何不應該成爲問題的形式的東西。再一次,只爲了這個目的,回調出來是正確的。過度打擊是什麼意思?這是否使上述答案的部分無效? – 2012-01-12 17:07:12