Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Pinvoke错误堆栈不平衡-lzo解压C函数_C#_.net_Pinvoke_Dllimport_Lzo - Fatal编程技术网

C# Pinvoke错误堆栈不平衡-lzo解压C函数

C# Pinvoke错误堆栈不平衡-lzo解压C函数,c#,.net,pinvoke,dllimport,lzo,C#,.net,Pinvoke,Dllimport,Lzo,我知道这个问题已经被问了好几次,具体如下: () 但我使用的是一个开源DLL,LZO 2.0.3,用ANSI C编写。有关DLL的信息如下: 我的C#程序是一个下载程序,它与通过TCP连接发送LZO压缩数据包的服务器建立TCP套接字 在.NET中有几个LZO端口,例如: [过时] 与.NET中的多个LZO和miniLZO端口不同,它们有自己的解压缩功能,根据数据包的最后4位建立目标缓冲区的长度,我的数据包包含未压缩的8字节头,如下所示: Header: 4 bytes - numb

我知道这个问题已经被问了好几次,具体如下: ()

但我使用的是一个开源DLL,
LZO 2.0.3
,用ANSI C编写。有关DLL的信息如下:

我的C#程序是一个下载程序,它与通过TCP连接发送LZO压缩数据包的服务器建立TCP套接字

在.NET中有几个LZO端口,例如:

[过时]

与.NET中的多个LZO和miniLZO端口不同,它们有自己的解压缩功能,根据数据包的最后4位建立目标缓冲区的长度,我的数据包包含未压缩的8字节头,如下所示:

Header:
  4 bytes - number of packets [bytes] in the incoming packet
  4 bytes - length of decompressed data packet

Data:
  X bytes - what needs to be decompressed 
[DllImport(LzoDLL64bit)]
private static extern int lzo1x_decompress_safe(byte[] src, int src_len, byte[] dst, ref int dst_len, byte[] wrkmem);
以下是我的代码片段:

Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
client.Connect(remoteEP);
while (true)
//infinite loop since the client keeps receiving data 
{
    m = client.Receive(inStream);
    //instream is previously defined as a byte of 100000
    //this is followed by code copying the m bytes received from inStream
    //to a new byte original
    short iNoOfPackets = 0;
    short myPacketLength = 0;
    //this is followed by code to extract the two variables above
    //from the first 8 bytes of original (or inStream)
    if (m > 8)
    {
        compressedData = new byte[m - 8];
        Array.Copy(original, 8, compressedData, 0, compressedData.Length);
    }
    byte[] destination = new byte[myPacketLength];
    try
    {
        int destlen = (int)myPacketLength;
        r = lzo1x_decompress_safe(compressedData, (int)compressedData.Length, destination, ref destlen, null);
    }
    catch (Exception ex)
    ....
使用PInvoke的函数调用如下所示:

Header:
  4 bytes - number of packets [bytes] in the incoming packet
  4 bytes - length of decompressed data packet

Data:
  X bytes - what needs to be decompressed 
[DllImport(LzoDLL64bit)]
private static extern int lzo1x_decompress_safe(byte[] src, int src_len, byte[] dst, ref int dst_len, byte[] wrkmem);
我正在64位Windows Server 2008计算机上使用Visual Studio 2012 Express

正如本文标题所示,我收到的错误是:

    Additional Information: A call to PInvoke function 'My.Program::lzo1x_decompress_safe' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.
调试控制台产生以下输出:

    4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
    'MyProgra.vshost.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Xml\v4.0_4.0.0.0__b77a5c561934e089\System.Xml.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
    A first chance exception of type 'System.Net.Sockets.SocketException' occurred in System.dll
    The program '[6852] Myprogram.vshost.exe: Managed (v4.0.30319)' has exited with code -1073741510 (0xc000013a).
如果您查看LZO 2.0.3库的源代码,特别是文件lzo1x.h,它会说:

/* safe decompression with overrun testing */
LZO_EXTERN(int)
lzo1x_decompress_safe   ( const lzo_bytep src, lzo_uint  src_len,
                            lzo_bytep dst, lzo_uintp dst_len,
                            lzo_voidp wrkmem /* NOT USED */ );

我的问题很简单-如何解决错误?作为一名C#程序员新手,我对C知之甚少,我不熟悉PInvoke,如果您有任何具体建议,我将不胜感激。对于可能重复的问题/场景提前道歉

默认的调用约定是StdCall,但是LZO似乎使用Cdecl,因此需要将其添加到DllImport声明中。以前版本的.NET运行时可能已默默地修复了该问题,但在.NET 4.0及更高版本中,当指定了错误的调用约定时,会发生这种情况

为了提高与非托管代码的互操作性,平台调用中不正确的调用约定现在会导致应用程序失败。在以前的版本中,封送层在堆栈上解决了这些错误

另外,最后一个参数是void*,但由于它未被使用,您可以将类型指定为IntPtr并传递IntPtr.Zero,它是C/C++中NULL的等价物

[DllImport(lzodll64位,CallingConvention=CallingConvention.Cdecl)]
专用静态外部接口lzo1x解压安全(字节[]src,uint src len,字节[]dst,参考uint dst len,IntPtr wrkmem);

此外,您似乎已编组uint->int。这可能是为了避免以后强制转换,但这可能会导致可能的负值。

以下签名不同-src_len是uint not int,dst_len是ref uint not int,这并不重要,但最后一个参数wrkmem有comment/*not USED/这是void pointer这可以是object,也可以是不安全c#pointers中的void,也可以是intptr谢谢,这太完美了!不仅错误得到了解决,而且您还省去了我发布另一个关于不断导致程序崩溃的负值(src_len/dest_len)的问题的麻烦。我将在服务器几小时后恢复联机后重新测试。