in .Net 4: PInvokeStackImbalance Exception

心不动则不痛 提交于 2019-12-12 15:37:35

问题


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?


回答1:


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



回答2:


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



回答3:


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.




回答4:


Just for fun :

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


来源:https://stackoverflow.com/questions/2723021/in-net-4-pinvokestackimbalance-exception

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!