in .Net 4:PInvokeStackImbalanceexception
我在.Net 3.5项目中使用了msvcrt.dll
中的strlen
函数。 进一步来说:
private unsafe static extern int strlen( byte *pByte );
迁移到.NET 4.0后,如果我使用此函数,则会抛出PInvokeStackImbalance
exception。
如何导入.NET 3.5 msvcrt.dll
或修复此exception?
我怀疑问题在于调用约定,你应该使用Cdecl。
[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)] private unsafe static extern int strlen(byte* pByte);
这不是一个直接的答案,但似乎对于像这样的function,编写自己的东西可能更好。 例如,以下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; }