问题描述
嗨,我想在 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
它的工作没有问题
谢谢
解决方法
我看到一个问题:
- VersionDate 没有 64/32 位检查,因此您总是调用 64 位版本,假设您的主程序为这两种 64/32 情况调用它,我无法分辨,因为您没有发布您的使用情况代码示例。 (您不会在问题中说是 64/32 还是两者都崩溃)。