![](/img/trans.png)
[英]PInvokeStackImbalance exception when using IntPtr in .NET 4? (Works in .NET 3.5)
[英]in .Net 4: PInvokeStackImbalance Exception
我在.Net 3.5項目中使用了msvcrt.dll
中的strlen
函數。 進一步來說:
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應該沒有任何變化。(而且,順便說一句,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也會這樣做。
純娛樂 :
public static unsafe int strlen(void* buffer)
{
byte* end = (byte*)buffer;
while (*end++ != 0);
return(int)end - (int)buffer - 1;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.