2017-07-10 97 views
0

我得到一個Delphi DLL,其中包含我需要在C#中調用的函數。其中一個函數需要兩個char數組,其中一個是加密的密碼,另一個是密鑰。如何從C#中的DLL調用此Delphi函數?

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

我試圖找出如何調用我自己的這個功能,但我不斷收到「無法元帥‘返回值’:無效的託管/非託管類型組合。」我使用字節,因爲Delphi中的Char類型是AnsiChar,它是8位。

[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開發人員使用Char而不是Byte來馬虎。 –

+0

@DavidHeffernan Delphi開發人員說他使用的字符類型是AnsiChar,所以它是8位 –

回答

3

我想我會傾向於將定長數組包裹在C#結構中。

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

這使得大小隻能在一個地方指定。

下一個障礙是返回值。德爾福ABI將一個不適合寄存器的返回值視爲額外隱藏的var參數。我將把它翻譯爲C#out參數。

最後,這兩個輸入參數被聲明爲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

是的,我搞砸了兩個參數。嘗試最新的編輯。 –

+0

我試過你的方法。現在可以調用該方法,但輸出始終是一組空值。你認爲這是C#代碼還是Delphi DLL? –