4

私はデルファイで手順を持っています:

procedure PasswordDLL(month  integer; password  pchar); 
export;

この手順では、渡した「 password 」 pcharにパスワードを出力する必要があります。

私は思いつきます:

[DllImport(
    "DelphiPassword.dll",
    CallingConvention = CallingConvention.StdCall,
    CharSet = CharSet.Ansi,
EntryPoint = "PasswordDLL")]
public static extern void PasswordDLL(    
    int month,
    [MarshalAs(UnmanagedType.LPStr)] string password
    ); 

次に、私が電話すると:

string pass = "";
PasswordDLL(2, pass);

したがって、「pass」文字列に出力するパスワード。

しかし、BadImageFormatException was unhandled: 正しくない形式のプログラムを読み込もうとしました。(HRESULT からの例外: 0x8007000B)

私が使用した関数形式が間違っているように聞こえますか? PChar に間違った UnmanagedType を使用したのだろうかと思いますが、読みからすると、LPWStr と LPStr のどちらかです。

前もって感謝します...

4

1 に答える 1

2

最初に、どのバージョンの Delphi を使用しているかを述べていないので、 Delphi 6に精通しているという理由だけで、Delphi 6を想定して回答します。

Delphi プロシージャは、その宣言で呼び出し規約を指定していないため、インポートに従ってstdcallを使用しません。最初のいくつかのパラメータをスタックではなくレジスタに配置する、デフォルトの Delphiレジスタ規則を使用します。Delhpi DLL を変更できる場合は、stdcall を追加します。宣言と再構築の後、呼び出し規約が一致します。

次の表は、呼び出し規約をまとめたものです。

Directive Parameter order Clean-up Passes parameters in registers?
--------- --------------- -------- -------------------------------
register  Left-to-right   Routine  Yes
pascal    Left-to-right   Routine  No
cdecl     Right-to-left   Caller   No
stdcall   Right-to-left   Routine  No
safecall  Right-to-left   Routine  No

.NET のドキュメントを見ると、Delphi のレジスタ規則 (下の表を参照)と一致する呼び出し規則がないように思われるため、Delphi DLL の規則を変更するしか選択肢がないと思います。

Member name   Description
-----------   ------------------------ 
Cdecl         The caller cleans the stack. This enables calling functions with   varargs, which makes it appropriate to use for methods that accept a variable number of parameters, such as Printf.
FastCall      This calling convention is not supported.
StdCall       The callee cleans the stack. This is the default convention for calling unmanaged functions with platform invoke.
ThisCall      The first parameter is the this pointer and is stored in register ECX. Other parameters are pushed on the stack. This calling convention is used to call methods on classes exported from an unmanaged DLL.
Winapi        Supported by the .NET Compact Framework. This member is not actually a calling convention, but instead uses the default platform calling convention. For example, on Windows the default is StdCall and on Windows CE .NET it is Cdecl.

Delphi (6) Pchar (null で終了する ANSI 文字列へのポインター) マーシャリングは正しく見えます。

于 2011-02-23T15:48:22.060 に答える