我整天都在研究这个问题,我仍然坚持下去 我把这个代码从c / c ++移植到c#im这么近但我得到了这些例外
抛出了类型'System.ExecutionEngineException'的异常。 和 尝试读取或写入受保护的内存。这通常表明其他内存已损坏。
这里是代码,代码没有清理/优化但导致我仍然在测试它
public unsafe static void GetHash(string data, byte[] hash)
{
byte[] input = System.Text.UnicodeEncoding.Unicode.GetBytes(data);
hash = new byte[128];
IntPtr hProv = IntPtr.Zero;
IntPtr hHash = IntPtr.Zero;
Crypto.CryptAcquireContext(ref hProv, string.Empty, string.Empty, Crypto.PROV_RSA_FULL, 0);
if (Crypto.CryptCreateHash(hProv, Crypto.CALG_SHA1, IntPtr.Zero, 0, ref hHash))
{
if (Crypto.CryptHashData(hHash, input, ((input.Length) + 1) * 2, 0))
{
byte[] buffer = new byte[20];
IntPtr pBuffer = IntPtr.Zero;
int length = 20;
if (Crypto.CryptGetHashParam(hHash, Crypto.HP_HASHVAL, ref pBuffer, ref length, 0))
{
Crypto.CryptDestroyHash(hHash);
Crypto.CryptReleaseContext(hProv, 0);
byte tail = 0;
unsafe
{
//no matter what i do it stops here!!!!! :(
//one error is "Exception of type 'System.ExecutionEngineException' was thrown."
//the other is "System.AccessViolationException crossed a native/managed boundary
//Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
try
{
//-------------------------- This is where the exepctions starts
//I have commented the code, cause im kinda getting tired of this Exception
//I tried 2 ways of getting a byte[] from a pointer
//the 1e way, does not work
//for (int i = 0; i < length; i++)
//buffer[i] = (byte)Marshal.ReadByte(pBuffer, i);
//the 2e way does not work
//System.Runtime.InteropServices.Marshal.Copy(pBuffer,buffer, 0, 20);
//--------------------------
}
catch (Exception ex)
{
}
}
//there is more code here, but i removed
//since i only want till where code goes sofare
}
}
}
}
希望有人可以帮助我,
Thnx提前
JB
答案 0 :(得分:2)
我在没有使用不安全或固定声明的情况下修复它,我所做的就像大多数编码tmp问题一样简单
我有这个类Crypto,我有所有advapi.dll函数,函数返回一个指向内存中字节数组的指针,这就是我改变之前所需的函数。
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CryptGetHashParam(
IntPtr hHash,
Int32 dwParam,
ref IntPtr pbData, // this is where my problem was!!!!
ref Int32 pdwDataLen,
Int32 dwFlags
我将功能更改为
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CryptGetHashParam(
IntPtr hHash,
Int32 dwParam,
Byte[] pbData, //i changed it from IntPtr to byte array
ref Int32 pdwDataLen,
Int32 dwFlags
这解决了我的腐败记忆问题 希望这个问题可以帮助其他人使用CryptGetHashParam
我从c / c ++移植了这段代码,因为网上没有c#样本,所以这里是第一个。
所有人都试图帮助我,但我自己修理了JB
答案 1 :(得分:1)
我不确定,但可能是因为你的.Net对象没有固定在内存中。见:http://dotnet.dzone.com/news/net-memory-control-use-gchandl。它的要点是.Net对象在你通过互操作传递后可以在内存中移动,当发生这种情况时,东西开始变得疯狂。
不幸的是,我现在正在使用上网本,不能自己尝试。这有帮助吗?