我在.net 3.5項目中使用msvcrt.dll
中的strlen
函數。更具體地講:in .Net 4:PInvokeStackImbalance異常
private unsafe static extern int strlen(byte *pByte);
遷移到.NET 4.0後,如果我用這個功能,它拋出一個PInvokeStackImbalance
例外。
如何導入.NET 3.5 msvcrt.dll
或修復此異常?
我在.net 3.5項目中使用msvcrt.dll
中的strlen
函數。更具體地講:in .Net 4:PInvokeStackImbalance異常
private unsafe static extern int strlen(byte *pByte);
遷移到.NET 4.0後,如果我用這個功能,它拋出一個PInvokeStackImbalance
例外。
如何導入.NET 3.5 msvcrt.dll
或修復此異常?
我懷疑問題是與調用約定,你應該使用Cdecl。
[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
private unsafe static extern int strlen(byte* pByte);
這不是一個真正的直接答案,但似乎對於像這樣的功能,它可能會更好地編寫自己的。例如,下面的C#代碼可能工作(雖然有可能是一個內襯使用現有的職能,將工作太):
static int mystrlen(byte[] pbyte)
{
int i = 0;
while (pbyte[i] != 0)
i++;
return i;
}
不應該有從.NET 3.5在這個任何變化爲4(和, btw,msvcrt.dll不是框架的一部分 - 它是Microsft C++運行時庫)。你確定你的項目沒有其他改變嗎?
我只是嘗試這樣的代碼,如預期其作品並打印「4」:
class Test
{
public unsafe static void Main(string[] args)
{
byte[] bytes = new byte[] {70, 40, 30, 51, 0};
fixed(byte* ptr = bytes)
{
int len = strlen(ptr);
Console.WriteLine(len);
}
}
[DllImport("msvcrt.dll")]
private unsafe static extern int strlen(byte* pByte);
}
這是我不清楚爲什麼你會不會想從託管代碼調用strlen的,但當然,你可能有你的理由。如果你需要一個替代管理的實施,這裏是一個班輪你可以使用:
private static int managed_strlen(byte[] bytes)
{
return bytes.TakeWhile(b => b != 0).Count();
}
當然,這並不多字節(Unicode)字符處理,但我不認爲strlen的會那樣做。
嗨Driis,謝謝你的迴應。我在不安全的代碼中使用它,我忘了提及它。我忘記了@ChrisTaylor:P的CallingConvention屬性 – SDReyes 2010-04-27 16:52:45
只是爲了好玩:
public static unsafe int strlen(void* buffer)
{
byte* end = (byte*)buffer;
while (*end++ != 0);
return(int)end - (int)buffer - 1;
}
謝謝克里斯。它再次像魅力一樣工作; )+1 – SDReyes 2010-04-27 16:53:16
太好了,我很高興它有幫助。 – 2010-04-27 17:03:42
+1我在今天的工作中遇到了同樣的問題,您的解決方案正是我所需要的。謝謝。 – 2010-08-20 19:16:46