美文网首页
Live-Server-7-bsdiff动态库的编译以及差分包的

Live-Server-7-bsdiff动态库的编译以及差分包的

作者: G63HH | 来源:发表于2019-08-03 15:26 被阅读0次

    bsdiff和bspatch是用来生成和应用二进制补丁的工具,也就是bsdiff通过新旧文件生成差分包,bspatch通过旧文件和差分包生成新文件,通过差分包的传输,能有效减少网络间传输的流量和时间。bsdiff和bspatch都是基于bzip2,并默认其位置在于/usr/bin。
    bsdiff和bspatch在运行时都需要消耗大量的内存空间和时间,假设n是旧文件的大小,m是新文件的大小,那么bsdiff需要的内存空间为max(17n, 9n+m)+O(1)字节;而bspatch需要n+m+O(1)字节。

    首先在bsdiff的官网中,可以直接下载bsdiff-4.3这个版本的源码,但是这个版本的源码仅仅支持Linux系统,不支持Windows系统的编译,就需要找到windows版本。

    windows下bsdiff的编译

    步骤如下:

    1. 查看main()函数需要什么参数
    2. 通过Java类,构建JNI头文件
    3. 将bsdiff源代码导入VS中并修改
    4. 通过VS将其编译成动态库

    1. 查看main()函数需要什么参数

    来看下bsdiff windows版本的文件目录:


    图片.png

    首先来看下bsdiff.cpp文件中main()函数有这么一行代码:

    if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]);
    

    表明main()函数需要传入4个参数,而第一个参数任意填,接着继续读main()函数的方法,可以得知剩余的3个参数分别是旧文件路径、新文件路径和差分包路径。

    2. 通过Java类,构建JNI头文件

    于是我们就可以编写Java代码和JNI代码。

    public class BsDiff {
    
        public native static void diff(String oldFile, String newFile, String patchFile);
    
        static {
    //        LibLoader.loadLib("Bsdiff.dll");
            LibLoader.loadLib("Bsdiff.so");
        }
    }
    

    编译,生成class文件后,通过Idea IDE生成jni头文件。在setting设置中,自定义如下工具


    javah工具.png

    随后调用该工具,就可以生成BsDiff这个类的JNI头文件。


    生成JNI头文件.png
    头文件如下:
    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_ljh_jni_BsDiff */
    
    #ifndef _Included_com_ljh_jni_BsDiff
    #define _Included_com_ljh_jni_BsDiff
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_ljh_jni_BsDiff
     * Method:    diff
     * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
     */
    JNIEXPORT void JNICALL Java_com_ljh_jni_BsDiff_diff
      (JNIEnv *, jclass, jstring, jstring, jstring);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    3. 将bsdiff源代码导入VS中并修改

    在VS中新建空白项目,将bsdiff windows的源代码、jni.h、jni_md.h和刚刚编译出来的JNI头文件导入到项目中。项目目录如下:


    图片.png

    随后就要修改源代码,使得整体调用逻辑变成通过JNI方法,调用bsdiff中原有的main()函数,生成差分包。
    将JNI头文件(com_ljh_jni_BsDiff.h)中的头文件引用修改为本地:

    #include <jni.h>     ->    #include "jni.h"
    

    在bsdiff.cpp源文件中,添加JNI头文件、修改main()函数名、添加JNI函数的实现。

    1. #include "com_ljh_jni_BsDiff.h"
    
    2.  int main(int argc,char *argv[]){ ... }  -> int bsdiff_main(int argc,char *argv[]){...}
    
    3. 
    //JNI调用
    JNIEXPORT void JNICALL Java_com_ljh_jni_BsDiff_diff
    (JNIEnv* env, jclass jcls, jstring oldfile_jstr, jstring newfile_jstr, jstring patchfile_jstr) {
        int argc = 4;
        char* oldfile = (char*)env->GetStringUTFChars(oldfile_jstr, NULL);
        char* newfile = (char*)env->GetStringUTFChars(newfile_jstr, NULL);
        char* patchfile = (char*)env->GetStringUTFChars(patchfile_jstr, NULL);
    
        //参数(第一个参数无效)
        char* argv[4];
        argv[0] = (char *)"bsdiff";
        argv[1] = oldfile;
        argv[2] = newfile;
        argv[3] = patchfile;
    
        bsdiff_main(argc, argv);
    
        env->ReleaseStringUTFChars(oldfile_jstr, oldfile);
        env->ReleaseStringUTFChars(newfile_jstr, newfile);
        env->ReleaseStringUTFChars(patchfile_jstr, patchfile);
    }
    

    4. 通过VS将其编译成动态库

    在项目属性中,添加编译的命令行来取消安全性检查之类的异常

    -D _CRT_SECURE_NO_WARNINGS -D _CRT_NONSTDC_NO_DEPRECATE 
    
    图片.png

    然后在常规设置中,将配置类型配置为动态库(.dll),即可编译。编译成功后,调用JNI中的


    图片.png

    Linux下bsdiff的编译

    在Linux中编译bsdiff的步骤与在windows中类似:

    1. 编译环境配置
    2. 通过Java类,构建JNI头文件
    3. 修改JNI头文件、源代码
    4. 编译成.so动态库

    1. 编译环境配置

    编译需要gcc和bzip2,通过如下指令安装bzip2

    sudo apt-get install libbz2-dev
    

    2.通过Java类,构建JNI头文件 3. 修改JNI头文件、源代码 参考windows编译

    4. 编译成.so动态库

    gcc bsdiff.c -lbz2 -fPIC -shared -o bsdiff.so
    

    相关文章

      网友评论

          本文标题:Live-Server-7-bsdiff动态库的编译以及差分包的

          本文链接:https://www.haomeiwen.com/subject/gvoddctx.html