2010-04-27 71 views
3

我在.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或修復此異常?

回答

10

我懷疑問題是與調用約定,你應該使用Cdecl。

[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)] 
private unsafe static extern int strlen(byte* pByte); 
+0

謝謝克里斯。它再次像魅力一樣工作; )+1 – SDReyes 2010-04-27 16:53:16

+0

太好了,我很高興它有幫助。 – 2010-04-27 17:03:42

+0

+1我在今天的工作中遇到了同樣的問題,您的解決方案正是我所需要的。謝謝。 – 2010-08-20 19:16:46

1

這不是一個真正的直接答案,但似乎對於像這樣的功能,它可能會更好地編寫自己的。例如,下面的C#代碼可能工作(雖然有可能是一個內襯使用現有的職能,將工作太):

static int mystrlen(byte[] pbyte) 
    { 
    int i = 0; 
    while (pbyte[i] != 0) 
     i++; 
    return i; 
    } 
1

不應該有從.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的會那樣做。

+0

嗨Driis,謝謝你的迴應。我在不安全的代碼中使用它,我忘了提及它。我忘記了@ChrisTaylor:P的CallingConvention屬性 – SDReyes 2010-04-27 16:52:45

1

只是爲了好玩:

public static unsafe int strlen(void* buffer) 
{ 
    byte* end = (byte*)buffer; 
    while (*end++ != 0); 
    return(int)end - (int)buffer - 1; 
}