自行封装的LZMA接口库,用于unity,包括win平台的dll,安卓的so动态库和iOS的.a静态库

LZMA是目前压缩比最高的压缩算法,官方提供了多种语言的版本,unity中可以直接使用C#版,但是实际证明纯C版的压缩速度是C#版的四五倍。

封装工程介绍

  1. LZMA(Xcode)是一个iOS的静态库工程,直接在xcode中run一下即可得到对应的.a静态库,顶层接口封装在LZMALib.c中;

  2. LZMA(AndroidStudio)是一个支持runtime C++的安卓工程,顶层接口封装在LZMALib.c中,build一下对应的.so库会装进apk包中,解压apk可以得到里面的LZMA so库(apk路径:..\app\build\outputs\apk\debug)。

  3. 7zSDK(VS)是LZMA官方完整的SDK和源码工程,编译LZMA动态库的工程是其中的LZMALib工程,路径为:..\C\Util\LzmaLib,顶层接口封装在LZMALib.c中。

封装接口预览

最顶层封装了两个接口,用于压缩和解压,压缩参数默认封在了接口内,如果要更改需要在相应的封装工程中修改并编译出新库:

// 自定义接口
    MY_STDAPI DefaultLzmaCompress(const unsigned char *src,const size_t srcLen,unsigned char *dest,size_t *destLen);
    MY_STDAPI DefaultLzmaUncompress(const unsigned char *src,size_t *srcLen,size_t *destLen);
    //MY_STDAPI LZMAAdd(int x); // 测试用
/* LzmaLib.c -- LZMA library wrapper #include "Alloc.h" #include "LzmaDec.h" #include "LzmaEnc.h" #include "LzmaLib.h" unsigned char outProps[LZMA_PROPS_SIZE]; size_t outPropsSize = LZMA_PROPS_SIZE; MY_STDAPI LzmaCompress(unsigned char *dest,size_t *destLen,const unsigned char *src,size_t srcLen,unsigned char *outProps,size_t *outPropsSize,int level,/* 0 <= level <= 9,default = 5 */
  unsigned dictSize,/* use (1 << N) or (3 << N). 4 KB < dictSize <= 128 MB */
  int lc,/* 0 <= lc <= 8,default = 3 */
  int lp,/* 0 <= lp <= 4,default = 0 */
  int pb,/* 0 <= pb <= 4,default = 2 */
  int fb,/* 5 <= fb <= 273,default = 32 */
  int numThreads /* 1 or 2,default = 2 */
)
{
  CLzmaEncProps props;
  LzmaEncProps_Init(&props);
  props.level = level;
  props.dictSize = dictSize;
  props.lc = lc;
  props.lp = lp;
  props.pb = pb;
  props.fb = fb;
  props.numThreads = numThreads;

  return LzmaEncode(dest,destLen,src,srcLen,&props,outProps,outPropsSize,0,NULL,&g_Alloc,&g_Alloc);
}

MY_STDAPI LzmaUncompress(unsigned char *dest,const unsigned char *src,const unsigned char *props,size_t propsSize)
{
  ELzmaStatus status;
  return LzmaDecode(dest,props,(unsigned)propsSize,LZMA_FINISH_ANY,&status,&g_Alloc);
}


// 自定义接口
MY_STDAPI DefaultLzmaCompress(const unsigned char *src,size_t *destLen)
{
    int level = 5;
    unsigned dictSize = 1 << 23;
    int lc = 3;
    int lp = 0;
    int pb = 2;
    int fb = 128;
    int numThreads = 1;
    return LzmaCompress(dest,&outPropsSize,level,dictSize,lc,lp,pb,fb,numThreads);
}

MY_STDAPI DefaultLzmaUncompress(const unsigned char *src,size_t *destLen)
{
    return LzmaUncompress(dest,outPropsSize);
}

MY_STDAPI LZMAAdd(int x)
{
    return x + 1;
}

使用方法示例

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;
using UnityEngine.UI;
public class Compress : MonoBehavIoUr {
    public Text text = null;
    [DllImport("LZMA")]
    public static extern int LZMAAdd(int x);
    [DllImport("LZMA")]
    public static extern int DefaultLzmaCompress(byte[] src,int srcLen,byte[] dest,ref int destLen);
    [DllImport("LZMA")]
    public static extern int DefaultLzmaUncompress(byte[] src,ref int srcLen,ref int destLen);
    // Use this for initialization
    void Start () {
        // 压缩
        string input = "122333444455555666666777777788888888999999999";
        byte[] src = System.Text.Encoding.Default.GetBytes(input);
        byte[] dest = new byte[src.Length];
        int srcLen = src.Length;
        int destLen = dest.Length;
        int compressRes = DefaultLzmaCompress(src,dest,ref destLen); // 压缩成功compressRes会返回0,destLen的值会变成压缩后的数据长度

        // 解压
        byte[] unsrc = new byte[destLen];
        for (int i = 0; i < destLen; i++) {
            unsrc[i] = dest[i]; // 将压缩后得到的dest数据复制到解压的src数据缓冲中
        }
        srcLen = destLen;
        destLen = src.Length;
        byte[] undest = new byte[destLen];
        int uncompressRes = DefaultLzmaUncompress(unsrc,ref srcLen,undest,ref destLen);
        string output = System.Text.Encoding.Default.GetString(undest); // 解压成功output应该和input值相同
    }

    // Update is called once per frame
    void Update () {

    }
}

工程地址(包括编译好的各平台的库,各平台的库工程和使用示例)

https://github.com/jiangxh1992/XHLZMA

用于Unity(windows\iOS\安卓)的纯C版LZMA压缩算法库dll .so和.a的更多相关文章

  1. ios – ld:找不到框架(自制框架)

    我正在尝试在Ipad上部署一个项目,其中包含一个名为“HelloUnity.framework”的自制框架.当我尝试部署我的项目时,我收到以下错误:更加具体:而且我不知道为什么,因为我的框架存在且框架的文件夹不为空.怎么了?谢谢,解决方法由于iOS不支持共享库,因此您需要确保您的框架正在编译为静态库.我不确定这部分,但你可能不得不链接静态库而不是框架(即,即使你的框架是静态的,’-framewor

  2. ios – 错误:您不能从游戏中删除Unity启动画面

    我正试图在Xcode中运行我的Unity游戏.在UnityiOS播放器设置中配置“DeviceSDK”时,一切都很好.但是当我切换到’模拟器SDK'时,在我的游戏启动时Xcode中出现以下错误:您正在使用UnityiPhoneBasic.您不能从游戏中删除Unity启动画面.由于此错误,游戏在启动时崩溃.我在Unity播放器设置中没有更改任何关于启动画面的信息.那么这个问题可能是什么原因呢?我在Google上发现了一些关于此错误的结果,但似乎没有任何帮助……

  3. ios – Unity 3.5到Unity 4.5.4

    我正在尝试将我的旧UnityxCode(Unity3.5)项目更新为Unity(4.5.4).应用程序将使用此方法崩溃:UnitySendMessage([classNameUTF8String],[methodNameNameUTF8String],nil);请帮帮我.解决方法在Unity(4.5.4)中,他们使用这样的char参数:所以我们想改变这样的调用:

  4. 由于未编译着色器,Unity应用程序在iOS上崩溃

    我正在尝试为iOS构建我的Unity5.4.2f2应用程序.它没有编译错误.但是当我尝试使用Xcode8.0运行应用程序时,它立即崩溃,调试器报告以下错误.Failedcompiling:fragmentevaluationshaderWARNING:0:4:extension‘GL_EXT_frag_depth’isnotsupportedERROR:0:38:Useofundeclaredid

  5. android – 无法在统一java插件上使用google play服务

    我有一个用Java编写的Unity插件.在这个插件中,我需要使用新的GoogleAdvertisementID来执行此操作,我必须添加到Manifest文件中:当我编译时,Unity会抛出错误:我还尝试将GooglePlay服务jar添加到[lugins/Androif文件夹但是没有帮助.使它运作的正确方法是什么?解决方法要修复此错误,您必须将version.xml文件从android-sdk/e

  6. android – Unity手机游戏 – 应用程序内购买插件

    我正在开发一款使用Unity的移动游戏,虽然很容易让核心游戏循环运行,但我遇到了移动设备界面的一些问题,特别是苹果和谷歌提供的应用程序内购买功能.我听说有插件可以帮忙解决这个问题.是否有任何地方列出所有选项,可以让我轻松比较它们?

  7. Android – 在活动中嵌入Unity3d场景 – 需要取消注册接收器吗?

    问题我第一次开始玩游戏活动它工作正常但如果我关闭活动然后再次启动游戏活动我得到此错误...我试过的我在线搜索了很多,看起来我需要在onPause或onDestroy上调用类似的东西;…嵌入Unity场景我遵循的步骤是在2011年编写的.整个过程看起来真的很笨拙且没有文档记录.有没有更好的方法在Unity活动中嵌入Unity场景中的Unity场景?当然,将Unity场景添加到现有应用程序是一件相当普遍的事情吗?

  8. android – Facebook Unity sdk错误

    我在使用facebookunitysdk为android编译统一时遇到此错误:我不明白为什么会这样.我在OSX10.9.5上运行Unity4.6,我安装了最新版本的Java以及androidskd.谁能帮我?解决方法我从昨天开始和整个上午花在研究之后得到了同样的错误.我发现它是由最新的AndroidAPI版本21引起的.之后我通过删除SDK管理器中的所有API版本21软件包恢复到AndroidAPI版本20,一切恢复正常.希望能帮助到你.

  9. Android上的C#:Xamarin或Unity?

    还是有其他解决方案?

  10. AndroidStudio接入Unity工程并实现相互跳转的示例代码

    这篇文章主要介绍了AndroidStudio接入Unity工程并实现相互跳转,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

随机推荐

  1. static – 在页面之间共享数据的最佳实践

    我想知道在UWP的页面之间发送像’selectedItem’等变量的最佳做法是什么?创建一个每个页面都知道的静态全局变量类是一个好主意吗?

  2. .net – 为Windows窗体控件提供百分比宽度/高度

    WindowsForm开发的新手,但在Web开发方面经验丰富.有没有办法为Windows窗体控件指定百分比宽度/高度,以便在用户调整窗口大小时扩展/缩小?当窗口调整大小时,可以编写代码来改变控件的宽度/高度,但我希望有更好的方法,比如在HTML/CSS中.在那儿?

  3. 使用Windows Azure查询表存储数据

    我需要使用特定帐户吗?>将应用程序部署到Azure服务后,如何查询数据?GoogleAppEngine有一个数据查看器/查询工具,Azure有类似的东西吗?>您可以看到的sqlExpressintance仅在开发结构中,并且一旦您表示没有等效,所以请小心使用它.>您可以尝试使用Linqpad查询表格.看看JamieThomson的thispost.

  4. windows – SetupDiGetClassDevs是否与文档中的设备实例ID一起使用?

    有没有更好的方法可以使用DBT_DEVICEARRIVAL事件中的数据获取设备的更多信息?您似乎必须指定DIGCF_ALLCLASSES标志以查找与给定设备实例ID匹配的所有类,或者指定ClassGuid并使用DIGCF_DEFAULT标志.这对我有用:带输出:

  5. Windows Live ID是OpenID提供商吗?

    不,WindowsLiveID不是OpenID提供商.他们使用专有协议.自从他们的“测试版”期结束以来,他们从未宣布计划继续它.

  6. 如果我在代码中进行了更改,是否需要重新安装Windows服务?

    我写了一个Windows服务并安装它.现在我对代码进行了一些更改并重新构建了解决方案.我还应该重新安装服务吗?不,只需停止它,替换文件,然后重新启动它.

  7. 带有双引号的字符串回显使用Windows批处理输出文件

    我正在尝试使用Windows批处理文件重写配置文件.我循环遍历文件的行并查找我想要用指定的新行替换的行.我有一个’函数’将行写入文件问题是%Text%是一个嵌入双引号的字符串.然后失败了.可能还有其他角色也会导致失败.如何才能使用配置文件中的所有文本?尝试将所有“在文本中替换为^”.^是转义字符,因此“将被视为常规字符你可以尝试以下方法:其他可能导致错误的字符是:

  8. .net – 将控制台应用程序转换为服务?

    我正在寻找不同的优势/劣势,将我们长期使用的控制台应用程序转换为Windows服务.我们为ActiveMQ使用了一个叫做java服务包装器的东西,我相信人们告诉我你可以用它包装任何东西.这并不是说你应该用它包装任何东西;我们遇到了这个问题.控制台应用程序是一个.NET控制台应用程序,默认情况下会将大量信息记录到控制台,尽管这是可配置的.任何推荐?我们应该在VisualStudio中将其重建为服务吗?我使用“-install”/“-uninstall”开关执行此操作.例如,seehere.

  9. windows – 捕获外部程序的STDOUT和STDERR *同时*它正在执行(Ruby)

    哦,我在Windows上:-(实际上,它比我想象的要简单,这看起来很完美:…是的,它适用于Windows!

  10. windows – 当我试图批量打印变量时,为什么我得到“Echo is on”

    我想要执行一个简单的批处理文件脚本:当我在XP中运行时,它给了我预期的输出,但是当我在Vista或Windows7中运行它时,我在尝试打印值时得到“EchoisOn”.以下是程序的输出:摆脱集合表达式中的空格.等号(=)的两侧可以并且应该没有空格BTW:我通常在@echo关闭的情况下启动所有批处理文件,并以@echo结束它们,所以我可以避免将代码与批处理文件的输出混合.它只是使您的批处理文件输出更好,更清洁.

返回
顶部