2017-07-10 16 views
0

私はC#で呼び出す必要がある関数を含むDelphi DLLが与えられています。関数の1つが2つのchar配列をとります.1つは暗号化されたパスワードで、もう1つはキーです。C#のDLLからこのDelphi関数を呼び出す方法は?

TCString = array[0..254] of Char; 
... 
function Decrypt(const S, Key: TCString): TCString; stdcall; 

私は自分自身でこの関数を呼び出す方法を把握しようとしたが、私は入れません「『戻り値』をマーシャリングすることはできません:無効な/アンマネージドタイプの組み合わせを管理します」 DelphiのChar型は8ビットのAnsiCharであるため、バイトを使用しています。

[DllImport("path", CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] 
     public static extern byte[] Decrypt(byte[] S, byte[] Key); 

これをC#で呼び出す正しい方法は何ですか?

+0

これに対処する方法はいくつかあります。最初のステップは、CharがあなたのDelphiにあることを理解することです。それは8または16ビット幅ですか?それは8ビットであり、Delphiの開発者はByteではなくCharを使用していないと仮定しています。 –

+0

@DavidHeffernan Delphiの開発者は、彼が使用している文字の種類はAnsiCharだから、それは8ビットだと言った –

答えて

3

私はC#の構造体で固定長配列をラップする傾向があると思います。

public struct CString 
{ 
    [UnmanagedType.ByValArray(SizeConst=255)] 
    byte[] value; 
} 

これにより、1つの場所でのみサイズを指定できます。

次のハードルは戻り値です。 Delphi ABIは、レジスタに収まらない戻り値を、追加の隠し属性varとして扱います。私はそれをC#outパラメータとして解釈します。

最後に、2つの入力パラメータはconstと宣言されています。つまり、それらは参照によって渡されます。

ので、関数は次のようになります。

[DllImport(dllname, CallingConvention = CallingConvention.StdCall)] 
public static extern void Decrypt(
    [In] ref CString S, 
    [In] ref CString Key, 
    out CString Result 

)。

これはバイナリデータで動作する関数のように見えるので、これを意図的に使用しないようにしました。多くのDelphiプログラマは、しばしば混乱するような状況で、AnsiChar配列をバイト配列と置き換えて扱います。

+0

私はあなたの提案をしました。私は大きな進歩したようです。しかし、私は現在、 "保護されたメモリを読み書きしようとしましたが、これは他のメモリが壊れていることを示しています。 –

+0

ええ、私はoutパラメータで2つを混乱させました。最新の編集を試してください。 –

+0

あなたの方法を試しました。今ではメソッドを呼び出すことができますが、出力は常にヌルの配列です。あなたはそれがC#コードまたはDelphi DLLだと思いますか? –

関連する問題