在 lzo dll 中使用 lzo1c_1_compress 方法

问题描述

嗨,我想在 C# 中使用 lzo 压缩文件
我想用 lzo1c_1_compress 压缩它,但我不知道为什么它根本不起作用并使程序崩溃,这是我的代码

using System;
using System.Diagnostics;
using System.Runtime.InteropServices;

namespace Lzo64
{
    /// <summary>
    /// Wrapper class for the highly performant LZO compression library
    /// </summary>
    public class LZOCompressor
    {
        private static TraceSwitch _traceSwitch = new TraceSwitch("Simplicit.Net.Lzo","Switch for tracing of the LZOCompressor-Class");
        private const string LzoDll32Bit = @"lib32\lzo2.dll";
        private const string LzoDll64Bit = @"lib64\lzo2_64.dll";

        #region Dll-Imports


        [DllImport(LzoDll64Bit)]
        private static extern int __lzo_init_v2(uint v,int s1,int s2,int s3,int s4,int s5,int s6,int s7,int s8,int s9);

        //[DllImport(LzoDll32Bit)]
        //private static extern int __lzo_init3();
        [DllImport(LzoDll64Bit)]
        private static extern IntPtr lzo_version_string();
        [DllImport(LzoDll32Bit,EntryPoint = "lzo_version_string")]
        private static extern IntPtr lzo_version_string32();
        [DllImport(LzoDll64Bit)]
        private static extern string lzo_version_date();
        [DllImport(LzoDll64Bit)]
        private static extern int lzo1c_1_compress(byte[] src,int src_len,byte[] dst,ref int dst_len,byte[] wrkmem);
        [DllImport(LzoDll64Bit)]
        private static extern int lzo1c_decompress(byte[] src,byte[] wrkmem);

        [DllImport(LzoDll32Bit,EntryPoint = "lzo1c_1_compress",CallingConvention = CallingConvention.Cdecl)]
        private static extern int lzo1c_1_compress32(byte[] src,byte[] wrkmem);
        [DllImport(LzoDll32Bit,EntryPoint = "lzo1c_decompress",CallingConvention = CallingConvention.Cdecl)]
        private static extern int lzo1c_decompress32(byte[] src,EntryPoint = "__lzo_init_v2",CallingConvention = CallingConvention.Cdecl)]
        private static extern int __lzo_init_v2_32(uint v,int s9);

        #endregion

        private byte[] _workMemory = new byte[16384L * 4];

        public LZOCompressor()
        {
            int init = 0;
            if (Is64Bit())
            {
                Console.WriteLine("Im 64Bit");
                init = __lzo_init_v2(1,-1,-1);
            }
            else
            {
                Console.WriteLine("Im 32Bit");
                init = __lzo_init_v2_32(1,-1);
            }
            if (init != 0)
            {
                throw new Exception("Initialization of LZO-Compressor Failed !");
            }
        }



        /// <summary>
        /// Version string of the compression library.
        /// </summary>
        public string Version
        {
            get
            {
                IntPtr strPtr;
                if (Is64Bit())
                    strPtr = lzo_version_string();
                else
                    strPtr = lzo_version_string32();

                string version = Marshal.PtrToStringAnsi(strPtr);
                return version;
            }
        }

        /// <summary>
        /// Version date of the compression library
        /// </summary>
        public string VersionDate
        {
            get
            {
                return lzo_version_date();
            }
        }

        /// <summary>
        /// Compresses a byte array and returns the compressed data in a new
        /// array. You need the original length of the array to decompress it.
        /// </summary>
        /// <param name="src">Source array for compression</param>
        /// <returns>Byte array containing the compressed data</returns>
        public byte[] Compress(byte[] src)
        {
            if (_traceSwitch.TraceVerbose)
            {
                Trace.WriteLine(String.Format("LZOCompressor: trying to compress {0}",src.Length));
            }
            byte[] dst = new byte[src.Length + src.Length / 64 + 16 + 3 + 4];
            int outlen = 0;
            if (Is64Bit())
                lzo1c_1_compress(src,src.Length,dst,ref outlen,_workMemory);
            else
                lzo1c_1_compress32(src,_workMemory);

            if (_traceSwitch.TraceVerbose)
            {
                Trace.WriteLine(String.Format("LZOCompressor: compressed {0} to {1} bytes",outlen));
            }
            byte[] ret = new byte[outlen + 4];
            Array.copy(dst,ret,outlen);
            byte[] outlenarr = BitConverter.GetBytes(src.Length);
            Array.copy(outlenarr,outlen,4);
            return ret;
        }

        private bool _calculated;
        private bool _is64bit;
        private bool Is64Bit()
        {
            if (!_calculated)
            {
                _is64bit = IntPtr.Size == 8;
                _calculated = true;
            }
            return _is64bit;
        }

        /// <summary>
        /// Decompresses compressed data to its original state.
        /// </summary>
        /// <param name="src">Source array to be decompressed</param>
        /// <returns>Decompressed data</returns>
        public byte[] Decompress(byte[] src)
        {
            if (_traceSwitch.TraceVerbose)
            {
                Trace.WriteLine(String.Format("LZOCompressor: trying to decompress {0}",src.Length));
            }
            int origlen = BitConverter.ToInt32(src,src.Length - 4);
            byte[] dst = new byte[origlen];
            int outlen = origlen;
            if (Is64Bit())
                lzo1c_decompress(src,src.Length - 4,_workMemory);
            else
                lzo1c_decompress32(src,_workMemory);

            if (_traceSwitch.TraceVerbose)
            {
                Trace.WriteLine(String.Format("LZOCompressor: decompressed {0} to {1} bytes",origlen));
            }
            return dst;
        }


    }

}

有人知道我做错了什么吗?
如果我使用任何其他方法,例如 lzo1x_1_compress 它的工作没有问题
谢谢

解决方法

我看到一个问题:

  1. VersionDate 没有 64/32 位检查,因此您总是调用 64 位版本,假设您的主程序为这两种 64/32 情况调用它,我无法分辨,因为您没有发布您的使用情况代码示例。 (您不会在问题中说是 64/32 还是两者都崩溃)。