4

我在 .Net 3.5 项目中使用该strlen功能。msvcrt.dll进一步来说:

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

迁移到 .NET 4.0 后,如果我使用此函数,它会引发PInvokeStackImbalance异常。

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

4

4 回答 4

11

我怀疑问题出在调用约定上,您应该使用 Cdecl。

[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
private unsafe static extern int strlen(byte* pByte);
于 2010-04-27T16:43:36.113 回答
1

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

  static int mystrlen( byte[] pbyte )
     {
     int i = 0;
     while ( pbyte[i] != 0 )
        i++;
     return i;
     }
于 2010-04-27T16:45:30.323 回答
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 也可以。

于 2010-04-27T16:47:34.367 回答
1

只是为了好玩 :

public static unsafe int strlen(void* buffer)
{
    byte* end = (byte*)buffer;
    while (*end++ != 0);
    return(int)end - (int)buffer - 1;
}
于 2010-04-27T16:56:19.667 回答