【发布时间】:2013-10-11 23:27:41
【问题描述】:
作为我上一个问题的后续,我终于导出了 C dll 并在 C# 中可用,但我一直在试图找出正确的参数类型和调用方法。
我在这里对 SO 进行了研究,但似乎没有关于如何分配变量类型的模式。
我看到有些人建议StringBuilder 用于uchar*,其他人建议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#
还有其他的,但这些是最新的。
【问题讨论】: