在.Net 4中:PInvokeStackImbalance异常

发布于 2024-08-31 04:17:04 字数 289 浏览 1 评论 0原文

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

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

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

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

I was using the strlen function from msvcrt.dll in a .Net 3.5 project. More specifically:

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

After migrating to .NET 4.0, if I use this function it throws a PInvokeStackImbalance exception.

How can I import the .NET 3.5 msvcrt.dll or fix this exception?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

淤浪 2024-09-07 04:17:04

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

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

I suspect that the problem is with the calling convention, you should be using Cdecl.

[DllImport("msvcrt.dll", CallingConvention=CallingConvention.Cdecl)]
private unsafe static extern int strlen(byte* pByte);
乱了心跳 2024-09-07 04:17:04

这实际上并不是一个直接的答案,但似乎对于像这样的功能,最好自己编写。例如,以下 C# 代码可能会起作用(尽管可能有一个使用现有函数的衬里也可以起作用):

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

This is not really a direct answer, but it seems that for something like this functionality, it might be better to write your own. For example, the following C# code might work (although there are probably one liners using existing functions that would work too):

  static int mystrlen( byte[] pbyte )
     {
     int i = 0;
     while ( pbyte[i] != 0 )
        i++;
     return i;
     }
阿楠 2024-09-07 04:17:04

从 .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 也不处理。

There should not be any changes in this from .NET 3.5 to 4. (and, btw, msvcrt.dll is not part of the framework - it is the Microsft C++ Runtime Library). Are you sure nothing else has changed in your project.

I just tried this code, which works and prints "4" as expected:

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);       
}

It is unclear to me why you would ever want to call strlen from managed code, but of course you might have your reasons. If you need an alternative managed implementation, here is a one liner you can use:

private static int managed_strlen(byte[] bytes)
{
    return bytes.TakeWhile(b => b != 0).Count();
}

Of course that does not deal with multi-byte (unicode) characters, but I don't think strlen does either.

来世叙缘 2024-09-07 04:17:04

只是为了好玩:

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

Just for fun :

public static unsafe int strlen(void* buffer)
{
    byte* end = (byte*)buffer;
    while (*end++ != 0);
    return(int)end - (int)buffer - 1;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文