我已经在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 写入,则标题文件肯定存在。将其追踪并从此作为您的来源工作。