2012-10-21 39 views
0

我已經搜索了周圍的Stackoverflow我遇到的問題,但他們都是非常具體的特定訪問衝突。模塊'MpLib.dll'中地址爲003B0E8E的訪問衝突。閱讀地址00120BF4

我認爲我遇到的一段代碼是一個叫做MpqExtractFile的函數,存儲在一個DLL中。

功能:

function MpqExtractFile(var hMPQ: Integer; szToExtract, szExtracted: AnsiString): Boolean; stdcall; external 'MpqLib.dll' name 'B2'; 

電話:

if MpqExtractFile(hMPQ, 'war3map.j', AnsiString(tempDir+'\war3map.j')) = True 
then ShowMessage('Success.') 
else ShowMessage('Failed.'); 

在此代碼的執行我的應用程序拋出的訪問衝突錯誤,因此ShowMessage不顯示在所有。

我不確定上述情況是否足以估計出問題所在,但如果還有其他問題,請告訴我。

編輯

這是VB.NET源代碼的摘錄,我已經解釋:

Declare Function MpqExtractFile Lib "MpqLib.dll" Alias "B2" (ByVal hMPQ As Integer, ByVal szToExtract As String, ByVal szExtracted As String) As Boolean 

我顯然不熟悉其他語言的聲明,但我發現下面的函數在聲明VB函數的同一個VB文件中。

BOOL WINAPI MpqExtractFile(HANDLE hMpq, const char * szToExtract, const char * szExtracted); 

謝謝先進!

+2

如何在DLL中聲明「B2」? DLL編碼的語言是什麼 - 如果它不是Delphi,那麼'AnsiString'將不會工作,通常你需要使用PAnsiChar。 –

+0

它是如何聲明的?我不確定。我相信DLL是用C++編碼的。我現在會嘗試一下,看看它是否有所作爲。 – ple103

+0

如果在C或C++中,如果使用UTF-16,它肯定會是PAnsiChar或PChar。 Delphi AnsiString是一個非常不同的野獸。 –

回答

7

AnsiString是完全錯誤的類型使用,除非DLL在Delphi/C++ Builder中寫入,實際在其參數中使用AnsiString。如果是這種情況,您需要知道DLL寫入哪個版本的Delphi/C++ Builder,因爲AnsiString的內存佈局在2009年發生了變化。

在任何情況下,跨DLL邊界傳遞非POD數據,所以大多數DLL不會這樣做。相關參數最有可能是PAnsiChar,例如:

function MpqExtractFile(var hMPQ: Integer; szToExtract, szExtracted: PAnsiChar): Boolean; stdcall; external 'MpqLib.dll' name 'B2'; 

if MpqExtractFile(hMPQ, 'war3map.j', PAnsiChar(AnsiString(tempDir+'\war3map.j'))) then 
    ShowMessage('Success.') 
else 
    ShowMessage('Failed.'); 

其他需要考慮的要點:

1)不是所有的DLL使用stdcall調用約定。這是很常見的C語言編寫的DLL,像許多開源庫,使用替代cdecl調用約定:

function MpqExtractFile(var hMPQ: Integer; szToExtract, szExtracted: PAnsiChar): Boolean; cdecl; external 'MpqLib.dll' name 'B2'; 

2)C沒有像Delphi和C真正Boolean數據類型++做。 C代碼使用Byte甚至Integer來模擬Boolean並不罕見。

爲了在Delphi中使用DLL,您確實需要知道其導出函數的實際正確聲明。這在C/C++中不是什麼問題,因爲大多數DLL都伴隨着。提供聲明的h文件。你有這樣的.h文件嗎?如果是這樣,請在此發佈,以便有人可以驗證您的翻譯到德爾福。

更新:

基於新的信息,正確的德爾福的聲明是這樣的:

function MpqExtractFile(hMpq: THandle; const szToExtract, szExtracted: PAnsiChar): BOOL; stdcall; external 'MpqLib.dll' name 'B2'; 
+0

我已經能夠找到DLL的源代碼,但未成功在找到原始文章中提到的函數,因爲有各種.h和.cpp文件。可以在這裏找到源代碼:http://files.magosx.com/download.php?file=MpqLibSource.zip – ple103

+0

該項目是對於.Net程序集而言,不是一個DLL –

+0

對於Remy帶來的不便,在包含我一直試圖解釋的函數的同一個VB文件中,我有fou nd其他一些聲明。我也將它添加到原始帖子中。 – ple103

4

你VB.net聲明:

Declare Function MpqExtractFile Lib "MpqLib.dll" Alias "B2" (
    ByVal hMPQ As Integer, ByVal szToExtract As String, 
    ByVal szExtracted As String) As Boolean 

等效德爾福進口會成爲:

function MpqExtractFile(MpqExtractFile: Integer; 
    szToExtract, szExtracted: PAnsiChar): BOOL; 
    stdcall; external 'MpqLib.dll' name 'B2'; 

Delphi字符串類型不應該用於互操作。 p/invoke編組器將String映射到C++ char *,它是Delphi中的PAnsiChar。

這種任務確實應該用C++頭文件來完成。你說你沒有那個。如果DLL是用C++編寫的,那麼頭文件肯定存在。它會支付它來追蹤它,並以此作爲你的來源。

相關問題