模块"MpLib.dll"中地址 003B0E8E 的访问冲突。读取地址 00120BF4



我已经在stackoverflow上搜索了我所遇到的问题,但是对于特定的访问违规行为,它们都非常具体。

我相信我遇到的代码片段是一个称为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);

谢谢您的高级!

AnsiString是完全错误的类型,除非DLL在Delphi/C 构建器中写入,并且实际上在其参数中使用了AnsiString。如果是这样,您需要知道Delphi/C 构建器DLL的写入,因为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文件吗?如果是这样,请在此处发布,以便有人可以验证您的翻译到Delphi。

更新:

基于新信息,正确的Delphi声明是:

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

您的vb.net声明为:

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

等效的delphi导入将是:

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

delphi字符串类型不应用于Interop。P/调用MAMSHALLER地图字符串到C char*,这是Delphi中的Pansichar。

确实应该使用C 标头文件执行此类任务。你说你还没有。如果DLL用C 写入,则标题文件肯定存在。将其追踪并从此作为您的来源工作。

最新更新