0

私が抱えていた問題について 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);

よろしくお願いします!

4

2 に答える 2

7

AnsiStringDLL が Delphi/C++Builder で記述されていて、実際AnsiStringにそのパラメータで使用されていない限り、使用するのは完全に間違った型です。その場合、AnsiString2009 年にメモリ レイアウトが変更されたため、DLL が記述された Delphi/C++Builder のバージョンを知る必要があります。

いずれにせよ、POD 以外のデータを DLL の境界を越えて渡すことは非常に危険であるため、ほとんどの 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呼び出し規約を使用しているわけではありません。cdecl多くのオープンソース ライブラリと同様に、C で記述された DLL が代わりに呼び出し規約を使用することは珍しくありません。

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

Boolean2) C には、 Delphi や C++ のような真のデータ型はありません。ByteC コードで を使用したりInteger、模倣することさえ珍しくありませんBoolean

Delphi で DLL を使用するには、エクスポートされた関数の実際の適切な宣言を知る必要があります。ほとんどの DLL には、宣言を提供する付属の .h ファイルがあるため、これは C/C++ ではあまり問題になりません。そのような .h ファイルはありますか? その場合は、ここに投稿して、誰かが Delphi への翻訳を確認できるようにしてください。

アップデート:

新しい情報に基づくと、正しい Delphi 宣言は次のとおりです。

function MpqExtractFile(hMpq: THandle; const szToExtract, szExtracted: PAnsiChar): BOOL; stdcall; external 'MpqLib.dll' name 'B2';
于 2012-10-21T07:38:00.933 に答える
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

同等の Delphi インポートは次のようになります。

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

Delphi 文字列型は相互運用に使用しないでください。p/invoke マーシャラーは、String を Delphi の PAnsiChar である C++ char* にマップします。

この種のタスクは、実際には C++ ヘッダー ファイルで実行する必要があります。あなたはそれを持っていないと言います。DLL が C++ で記述されている場合、ヘッダー ファイルは確実に存在します。それを追跡し、それをソースとして作業することにはお金がかかります.

于 2012-10-21T21:10:55.317 に答える