在.Net 4中:PInvokeStackImbalance例外

时间:2010-04-27 16:29:09

标签: c# .net .net-4.0 msvcrt

我在.Net 3.5项目中使用strlen中的msvcrt.dll函数。更具体地说:

private unsafe static extern int strlen( byte *pByte );

迁移到.NET 4.0后,如果我使用此函数,则会抛出PInvokeStackImbalance异常。

如何导入.NET 3.5 msvcrt.dll或修复此异常?

4 个答案:

答案 0 :(得分:11)

我怀疑问题在于调用约定,你应该使用Cdecl。

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

答案 1 :(得分:1)

这不是一个直接的答案,但似乎对于类似这个功能的东西,编写自己的东西可能更好。例如,以下C#代码可能有效(尽管可能有一个使用现有函数的衬垫也可以工作):

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

答案 2 :(得分:1)

从.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也不会这样做。

答案 3 :(得分:1)

只是为了好玩:

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