作爲我之前問題的後續工作,我最終得到了C dll導出並可在C#中使用,但我試圖弄清楚正確的參數類型並調用方法。確定DLLImport參數並安全地調用非託管C函數
我在這裏研究過SO,但似乎沒有一個模式來指定變量類型。
我看到一些人建議爲uchar*
一個StringBuilder
,別人byte[]
,以「不安全」的代碼中的一些參考等誰能推薦在此基礎上具體使用情況的解決方案?
還要注意現在代碼立即生成的異常,就在調用C函數之後。
C函數進口:
[DllImport("LZFuncs.dll")]
internal static extern long LZDecomp(ref IntPtr outputBuffer, byte[] compressedBuffer, UInt32 compBufferLength); //Originally two uchar*, return is size of uncompressed data.
C函數簽名:
long LZDecomp(unsigned char *OutputBuffer, unsigned char *CompressedBuffer, unsigned long CompBufferLength)
使用如下:
for (int dataNum = 0; dataNum < _numEntries; dataNum++)
{
br.BaseStream.Position = _dataSizes[dataNum]; //Return to start of data.
if (_compressedFlags[dataNum] == 1)
{
_uncompressedSize = br.ReadInt32();
byte[] compData = br.ReadBytes(_dataSizes[dataNum] - 4);
IntPtr outData = IntPtr.Zero;
LZFuncs.LZDecomp(ref outData, compData, Convert.ToUInt32(compData.Length));
var uncompData = new byte[_uncompressedSize]; //System.ExecutionEngineException was unhandled
Marshal.Copy(outData, uncompData, 0, Convert.ToInt32(_uncompressedSize));
BinaryWriter bw = new BinaryWriter(new FileStream("compData" + dataNum + ".txt", FileMode.CreateNew));
bw.Write(uncompData);
bw.Close();
}
else
{
BinaryWriter bw = new BinaryWriter(new FileStream("uncompData" + dataNum + ".txt", FileMode.CreateNew));
bw.Write(br.ReadBytes(_dataSizes[dataNum]));
bw.Close();
}
}
我假設C代碼是相當嚴重的,如果它是重挫內存用這樣的CLR異常打破C#調用者,但由於C代碼的寫法,絕對沒有辦法修改它而不會破壞功能,它實際上是一個黑匣子。 (用匯編寫的,在大多數情況下)。
僅供參考,只是我一直在努力讀了一些問題,這個解決自己:
How do I return a byte array from C++ to C#
Correct way to marshall uchar[] from native dll to byte[] in c#
有已成爲其他人,但這些是最近的。
謝謝你,那確實起作用。我認爲C++ long在代碼中的其他地方長度不同,但不在導入中。同時在修復了您發佈的代碼後,在我使用_dataSizes而不是_dataOffset的原始代碼中發現了錯誤完美。非常感激! – Tigress