类库大魔王/missdeer 2017-09-04T01:25:00+00:00 me@minidump.info 一种Firefox同步失败的情况 2017-09-04T00:00:00+00:00 类库大魔王/missdeer https://blog.minidump.info/2017/09/a-kind-of-firefox-sync-failure 前些天突然发现家里台式机(Windows 10)上的Firefox不能工作了,具体表现是:

  • 同步不正常
  • 某些https网页打不开
  • 重装后变本加厉,所有https网页都打不开了,同步账户也登录不进了(因为会跳转到一个https页面)

无论我如何删光Firefox的数据,如何重装Firefox,装不同版本的Firefox都是同样的现象,就差重装系统了(估计重装系统都没用)。

本来也怀疑过是家里网络的原因,但是另一个装了32位Windows 10的平板上的Firefox却是工作得好好的样子,所以也觉得跟网络的关系不大。

昨天又开始折腾,偶然想到Firefox只是SSL证书握手失败,想来还是网络的缘故。于是拿出联通日租卡MIFI,把台式机上的有线网络(电信)禁用,走MIFI,果然一切都正常了。

究其原因,我家里的网络在路由器上屏蔽了一系列的域名,估计是把一些Firefox或SSL证书验证相关的域名屏蔽掉了,具体是哪些域名就不清楚了。

]]>
一次装Windows的经历 2017-08-16T00:00:00+00:00 类库大魔王/missdeer https://blog.minidump.info/2017/08/install-windows7 妹子新工作居然要求自带电脑,然后就报到前一天晚上开始折腾一台老ASUS笔记本,结果折腾得自己改坏了系统登录密码,再也进不去系统,只能重装解决。

说起来已经好多年不装系统了,年纪越大越懒得折腾。从抽屉翻出好久没用过的U盘准备做安装盘,结果用Win32DiskImager烧了几次U盘都不能启动,我以为是备份的镜像文件有问题,打算第二天去公司找好用的镜像再做。

第二天到公司问同事要到了中文Windows7旗舰版的镜像和序列号,顺便问了一下同事用什么软件烧录,才意识到可能是Win32DiskImager不能直接把ISO烧成启动盘。然后用了Rufus,成功烧录一个U盘,另一个U盘试了好几次都在格式化阶段出问题失败了,最后用Windows7 USB DVD Download Tool烧录成功。

安装Windows系统本身并没什么值得说的,从U盘启动即可。安装完系统,用驱动精灵装好各种驱动,重启了n次后,开始装妹子需要的Office,搜狗输入法和360浏览器。

Office的镜像幸亏我在两个U盘上都拷贝了,居然有一个U盘上的镜像加载后,安装程序说校验不通过,不能安装,还好另一个U盘上的正常安装了。从公司拿了几个序列号,有一个填上说已经超过最大激活次数,只好换掉,要从控制面板-卸载程序那里点“更改”按钮找到换序列号的界面。

用驱动精灵装搜狗输入法,结果装了个假的搜狗输入法,输入法没装反而把腾讯电脑管家全家桶给装上了,从任务管理器上可以看到一下多了十来个名字是QQ开头的进程,360浏览器都不能打开了,系统关机都一直转圈,最后强行按电源键才关机重启,再次进入系统直接把全家桶卸载掉,才恢复正常。

只能说,国内的环境太恶劣了。

]]>
C++11 lambda表达式tips 2017-08-13T00:00:00+00:00 类库大魔王/missdeer https://blog.minidump.info/2017/08/cxx11-lambda-tips C++11加入的lambda表达式是一大进步,大概这样用:

int a = 1;
auto f = [&a](int n)->int {
    return n+a;
};
int b = f(2);

这段代码定义了一个lambda表达式,接受一个int变量参数,返回一个int值,同时又要捕获(即在lambda表达式内访问)外部变量a的引用。

这里有一些tips:

  1. 捕获内建类型变量,即不是class/struct的实例的,如果没有修改的需求,传值比传引用要效率少,一般少1条汇编指令。像上面代码中的&a,不如改成a

  2. 捕获变量列表可以指定多个变量,以逗号分隔,如果有很多变量都要被捕获,方便起见不如直接写一个[&][=],即全部捕获变量引用或全部捕获变量值,实际上编译器生成代码时,只会对lambda表达式中实际使用到的捕获变量生成相应的代码,没用到的都不会有任何冗余代码开销。

  3. 捕获变量如果以值传递,是只读的,在lambda表达式中不能修改,否则编译就会失败。

  4. 要注意捕获变量的生命周期,比如在一个范围内将lambda表达式作为回调体(callback entity)延迟调用,如果该lambda表达式的捕获变量已经被销毁(栈上分配的变量出了范围就自动销毁)再调用lambda表达式,则程序可能就crash了。

  5. lambda表达式虽然可以在函数体内定义,但实际上基本是个编译期行为,编译器会根据需要将lambda表达式作为一个独立的函数生成代码,比如以下代码:

    class C {
        public:
        void lambdaTest() {
            int a = 1;
            auto f = [&a](int n)->int {
                return n+a;
            };
            int b = f(2);
        }
    };
    
    void f() {
        C c;
        c.lambdaTest();
    }
    

    在gcc 7.1的实现中,会分别生成C::lambdaTest()C::lambdaTest()::{lambda(int)#1}::operator()(int) const两个函数的代码,除此之外clang/LLVM,Micrsoft Visual C++和Intel C++基本都是相同的做法。所以一般说来,逻辑上把lambda当成一个普通函数对待即可。但是从编程实践的角度讲,lambda表达式最好不要写太长,越短小越好,不然直接写个独立的函数代码结构会更好。

]]>
把blog托管到Coding Pages 2017-08-10T00:00:00+00:00 类库大魔王/missdeer https://blog.minidump.info/2017/08/host-by-coding-pages 自从重新开始写blog,都是托管在github pages上,然后通过cloudflare中转以及https证书。这一套方案总的说来工作得挺好的,但是,万事就怕但是,在大陆cloudflare的服务并不是特别稳定。后来发现Coding.net也提供Pages服务了,还集成了Let’s Encrypt的证书服务,于是就迁过去了。

迁过去有一些事要解决:

  1. 在Coding.net上创建一个新的仓库,添加一个remote:git remote add coding git@git.coding.net:missdeer/blog.git
  2. 因为Coding pages支持从master或coding-pages两种branch部署pages,所以直接把gh-pages推送上去即可:git push coding gh-pages:master
  3. 修改自定义域名的DNS设置,CNAME到pages.coding.me。
  4. 在页面中添加Coding Pages的声明。
  5. 到Coding Pages的设置页添加自定义域名,它不像github pages那样读根目录下的CNAME文件。
  6. 为自定义域名申请https证书以及申请去除跳转广告。

大功告成。目前看来Coding Pages在全球都有部署,在大陆也有,大大提升了在大陆的访问速度,只不过在github上的部署就废了。

网上有不少文章介绍coding pages和github pages双线部署,在我看来根本没必要,本来一个中文blog就没几个海外访问者,而且Coding pages在海外访问并不慢。

]]>
为4个平台编译Boost 2017-05-20T00:00:00+00:00 类库大魔王/missdeer https://blog.minidump.info/2017/05/build-boost-for-4-platforms 公司的项目至今仍在使用Boost 1.56.0版本,最近发现Boost.uuid在Windows上居然会一直尝试去访问/dev/urandom,进而转移到系统盘根目录urandom文件,然后客户认为这会有安全隐患,需要修正。我随手看了一下Boost.uuid在1.56.0和1.64.0上的源代码,貌似确实1.56.0版并没有分系统实现,在1.64.0上为Windows系统使用平台特有的实现。于是我就建议升级Boost,然后发现这个third party的owner居然是我们组,同事开玩笑地问我能不能去为几个平台编译一下Boost,我当场就拒绝了,但回到家我还是决定折腾一下。

  • Windows平台使用msvc 2015的话特别简单

    call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" x86
    
    set cores=%NUMBER_OF_PROCESSORS%
    echo Building boost with %cores% cores
    
    call bootstrap.bat
    
    rem Most libraries can be static libs
    b2 -j%cores% toolset=msvc-14.0 address-model=64 architecture=x86 link=static threading=multi runtime-link=shared --build-type=minimal stage --stagedir=stage/msvc2015-x64
    b2 -j%cores% toolset=msvc-14.0 address-model=32 architecture=x86 link=static threading=multi runtime-link=shared --build-type=minimal stage --stagedir=stage/msvc2015-x86
    
    pause
    
  • macOS和iOS平台使用了同一组脚本,从网上找的,我再自己稍做修改,macOS上只要x86_64架构的即可。

    iOS上需要armv7,arm64,i386,x86_64四种架构的。

  • Android平台的搞了很久,昨天晚上折腾到12点多,今天又折腾了一个白天,终于搞定。网上有许多各种方案,在Linux,Windows,macOS上都有,我在Windows 10上折腾了很多次都不行,最后在macOS上成功了。首先,仍然是先构建bjam:

    ./bootstrap.sh
    

    然后修改Boost根目录下的project-config.jam文件,用以下内容覆盖文件内容:

    import option ;
    
    using gcc : x86 : i686-linux-android-g++ ;
    using gcc : x86_64 : x86_64-linux-android-g++ ;
    using gcc : mipsel : mipsel-linux-android-g++ ;
    using gcc : mips64el : mips64el-linux-android-g++ ;
    using gcc : aarch64 : aarch64-linux-android-g++ ;
    using gcc : arm : arm-linux-androideabi-g++ ;
    
    option.set keep-going : false ;
    

    接着把Android NDK路径设置到环境变量中:

    export androidNDKRoot=$HOME/android-ndk-r14b
    

    最后运行bjam进行编译

    #!/bin/bash
    env PATH=$androidNDKRoot/toolchains/x86-linux-android-4.9/prebuilt/darwin-x86_64/bin/:$PATH ./bjam -j2 --reconfigure link=static threading=multi threadapi=pthread target-os=android stage --stagedir=android/x86 toolset=gcc-x86 define=BOOST_MATH_DISABLE_FLOAT128 include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/include include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86/include/ include=$androidNDKRoot/platforms/android-21/arch-x86/usr/include
    env PATH=$androidNDKRoot/toolchains/x86_64-linux-android-4.9/prebuilt/darwin-x86_64/bin/:$PATH ./bjam -j2 --reconfigure link=static threading=multi threadapi=pthread target-os=android stage --stagedir=android/x86_64 toolset=gcc-x86_64 define=BOOST_MATH_DISABLE_FLOAT128 include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/include include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/libs/x86_64/include/ include=$androidNDKRoot/platforms/android-21/arch-x86_64/usr/include
    env PATH=$androidNDKRoot/toolchains/arm-linux-android-4.9/prebuilt/darwin-x86_64/bin/:$PATH ./bjam -j2 --reconfigure link=static threading=multi threadapi=pthread target-os=android stage --stagedir=android/arm toolset=gcc-arm define=BOOST_MATH_DISABLE_FLOAT128 include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/include include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/include/ include=$androidNDKRoot/platforms/android-21/arch-arm/usr/include
    env PATH=$androidNDKRoot/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/:$PATH ./bjam -j2 --reconfigure link=static threading=multi threadapi=pthread target-os=android stage --stagedir=android/aarch64 toolset=gcc-aarch64 define=BOOST_MATH_DISABLE_FLOAT128 include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/include include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/libs/arm64-v8a/include/ include=$androidNDKRoot/platforms/android-21/arch-arm64/usr/include
    env PATH=$androidNDKRoot/toolchains/mips64el-linux-android-4.9/prebuilt/darwin-x86_64/bin/:$PATH ./bjam -j2 --reconfigure link=static threading=multi threadapi=pthread target-os=android stage --stagedir=android/mips64el toolset=gcc-mips64el define=BOOST_MATH_DISABLE_FLOAT128 include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/include include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/libs/mips64/include/ include=$androidNDKRoot/platforms/android-21/arch-mips64/usr/include
    env PATH=$androidNDKRoot/toolchains/mipsel-linux-android-4.9/prebuilt/darwin-x86_64/bin/:$PATH ./bjam -j2 --reconfigure link=static threading=multi threadapi=pthread target-os=android stage --stagedir=android/mipsel toolset=gcc-mipsel define=BOOST_MATH_DISABLE_FLOAT128 include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/include include=$androidNDKRoot/sources/cxx-stl/gnu-libstdc++/4.9/libs/mips/include/ include=$androidNDKRoot/platforms/android-21/arch-mips/usr/include
    

    这样可以编译出armeabi等共6种目前官方NDK支持的架构的静态库。

]]>
几个使用MinGW开发遇到的问题 2017-05-05T00:00:00+00:00 类库大魔王/missdeer https://blog.minidump.info/2017/05/resolved-mingw-programming-issue 之前提到过我用MinGW版本的Qt遇到几个问题,现在基本解决。

  • 不能编译Lua源代码。我在日志查看程序中嵌入Lua解释器来实现扩展功能,图省事把所有Lua源代码都拷到工程中,跟程序源代码一起编译,但在用MinGW编译时会报一些错误:

    D:\Works\dev\cjlv\3rdparty\lua-5.3.3\src\lobject.c:286: error: 'strcpy_instead_use_StringCbCopyA_or_StringCchCopyA' undeclared (first use in this function)
         strcpy(buff, s);  /* copy string to buffer */
         ^
    D:\Works\dev\cjlv\3rdparty\lua-5.3.3\src\luaconf.h:593: error: 'sprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA' undeclared (first use in this function)
     #define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i))
                                              ^
    

    这个问题可以通过在#include <strsafe.h>前定义一个宏STRSAFE_NO_DEPRECATE解决,比较简便的方式是在.pro文件中直接全局定义:DEFINES += STRSAFE_NO_DEPRECATE

    解决了这个问题后,重新编译,会遇到另一个错误:

    D:\Works\dev\cjlv\3rdparty\lua-5.3.3\src\lundump.c:88: error: conflicting types for 'LoadStringW'
     static TString *LoadString (LoadState *S) {
                     ^
    

    这是因为Lua源代码中定义的函数名LoadString跟Windows SDK中的宏LoadString冲突了,可以通过在lundump.c文件开头处添加:

    #ifdef _WIN32
      #pragma push_macro("LoadString")
      #undef LoadString
    #endif
    

    结尾处添加:

    #ifdef _WIN32
      #pragma pop_macro("LoadString")
    #endif
    

    即可解决。

  • 编译时找不到SHGetKnownFolderPath定义。这个API在Vista及以上版本的Window中存在,可以通过宏定义当前系统版本号解决:DEFINES += WINVER=0x0600 _WIN32_WINNT=0x0600

  • 链接时找不到IID_IImageList符号定义。网上说这个符号定义在uuid.lib中,但我在命令行参数中已经加了-luuid仍然报错,后来看到有人自己写一个也能工作:

    #if !defined(_MSC_VER)
        // For MinGW:
        static const IID iID_IImageList = {0x46eb5926, 0x582e, 0x4017, {0x9f, 0xdf, 0xe8, 0x99, 0x8d, 0xaa, 0x9, 0x50}};
        HRESULT hResult = SHGetImageList(imageListIndex, iID_IImageList, (void**)&imageList);
    #endif
    
  • 没有QtWebEngine。这个实在没办法了,Chroumium这个上游项目就不支持MinGW,Qt也无能为力。不过今天看到有个非官方的QtWebkit支持MinGW,实在需要的话可以试试。


另外,通过msys2安装的Qt可以直接使用msys2安装的库,比如quazip依赖的zlib,可以直接使用pacman -S mingw-w64-x86_64-zlib安装,之后LIBS += -lz即可,其他的诸如Boost,Lua之类的也可以如此直接使用。


最后我想说的是,用MinGW编译出来的程序运行起来似乎比用MSVC编译出来的程序运行要慢,肉眼可见的慢。

]]>
一些Qt tips 2017-05-02T00:00:00+00:00 类库大魔王/missdeer https://blog.minidump.info/2017/05/qt-tips Qt在Windows上支持众多编译器套件/版本,图省事可以直接从msys2的仓库通过pacman安装,有32位和64位,静态链接和动态链接总共4个包。还可以通过pacman安装Qt Creator,也有32位和64位共2个版本。经过简单试用下来发现,从msys2安装的Qt与从官网下载安装的MinGW版本Qt基本相同,但比MSVC版本要不好用些,我遇到几个问题不能解决:

  1. 编译Lua源代码失败
  2. 找不到SHGetKnownFolderPath定义
  3. 没有WebEngine

QtWebEngineCore在QT += webengine后就可以使用,但在macOS上deploy时浏览器独立进程并不能通过rpath找到链接的Frameworks,需要QT += webenginecore后解决。


Qt 5.8开源版本引入了一个QML Ahead-Of-Time编译功能,这个功能默认打开,程序使用.qml文件和.js文件会在程序第一次运行时自动编译成.qmlc文件和.jsc文件。编译后的文件之后会被程序自动装载使用,可以加速程序第二次及以后运行时装载QML文件的速度。编译后的文件存放在StandardPaths::writableLocation(QStandardPaths::CacheLocation)下面的qmlcache目录中。其实加速效果也了胜于无,比较期待商业版本中包含的QtQuick Compiler,本来说5.8开源版会有的,后来居然反悔了,之后什么时候会有开源版本就不一定咯。


另外发现一个现象,至少在Windows上很明显,使用静态编译的Qt生成的程序比动态编译的Qt生成的程序启动速度要快很多,我能想到的是从磁盘读取的东西少了,但即使是使用了SSD也仍然非常明显。不排除动态编译版本会多一些奇怪的初始化操作以致于拖慢了启动速度。

]]>
三清山两日游 2017-04-16T00:00:00+00:00 类库大魔王/missdeer https://blog.minidump.info/2017/04/sanqingshan-trip 这次team building大家投票选出了方案,去江西三清山游玩。本来以为是一条休闲级的线路,结果事实却是疯狂级!

三清山浏览示意图

周四下午5点钟从公司出发,一行11个大人1个4岁的男孩,6点多的动车到江西玉山南站是晚上9点多。出了站恶心的事情就发生了,车站出口并没什么出租车,只有大批的黑车,组织活动的同事跟他们谈价钱谈不好,用手机叫了滴滴专车,结果一群黑车司机骂骂咧咧不让那专车开走,专车是个戴眼镜的小青年,看起来文文弱弱的,跟那几个黑车司机用方言不知道说些什么,大概是在互相呛声。刚到江西就遇到这么一幕还真是挺让我觉得恶心的,虽然说这样的垃圾人哪哪都有,但在一个地方遇到了,我仍然会地图炮地觉得这块地方的人都不好。这种“车霸”其实市场并不大,估计也就他自以为了不起,旁边的一些黑车司机大多也只是跟着起哄而已,另外再有一些黑车司机估计也只是不想多事跟他计较而已。别说黑社会了,这种人估计连混混都算不上,只是做人做事在极小的范围内霸道些而已。最后我们一行还是分成一辆专车一辆七座黑车到了玉山县公共汽车站对面的7天连锁酒店。

在酒店草草过了一夜,6点多就起床,下楼在附近一个小店里吃了一笼小笼和一根油条,那小笼个头比其他地方的要大很多,皮厚馅少,但价格也不贵,才5块钱,可把我撑着了。之后去汽车站坐公交车直达三清山南门,路上大概花了80来分钟,晃得我有点晕车,也不知道是不是因为小笼吃撑了的缘故,后半程一直觉得恶心反胃。

我们从南门进去,没坐外双溪索道的缆车,而是一直徒步爬到日上酒店,在公交车上听人说快的人只要30多分钟就能爬到缆车站了,而我们爬了2个多小时!到日上时已经12点多了,旁边卖快餐的都已经收摊了,反来交涉了一下说可以从剩菜剩饭里提供几份快餐出来,毕竟40元一份呢,我们七个人,商家这个生意不做白不做啊。

吃过中饭稍做整理,开始爬山,沿着阳光海岸,到三清福地,绕过三清宫景区,再从西海岸回到日上,天已经快黑了,那家快餐店已经彻底关门歇业,门口已经跳起了广场舞!后来几番纠结下来,买了20元一盒的泡面当晚饭!

吃过晚饭,继续爬山,翻过一线天,目的地杜鹃山庄露营,天已经黑得伸手不见五指,幸亏一行人全是男的,两个女同事已经留在日上过夜,大概走了七八十分钟才到达。

周六凌晨4点半开始起床,去玉台看日出。天气总算还可以,5:40左右日出开始了,总共持续了没几分钟就太阳就整个跳出来了。然后回露营地吃早饭,是稀饭,总算是这两天来最好的一顿热饭了,内牛满面啊!

吃过早饭有几个同事继续爬山,我就和几个同事从金沙索道站下山了,然后从东门坐公交车回县里,把行李寄放在7天酒店,顶着烈日走去2.7公里外的御一品三汁焖锅,6个大人1个小孩点了两个锅共八个菜,饮料免费,大概总共点了12瓶啤酒,最后大众点评可以优惠买单,午市是78折,总共花费272元。

下午一起回到7天酒店开了一间钟点房,一直等到4点钟坐公交车到玉山南站坐高铁回上海,到家已经是晚上9:20左右了。

这一趟去三清山,有一些经验教训:

  • 对体力要求比较高,即使上山的时候可以坐一段缆车,后面仍然有很多路要徒步。这条线路看风景(看山看树看石头)是顺带,主要是锻炼身体的:( 不过遇到非常多的老年人,七八十岁的样子,所以年青人就算体力不行,也是可以去尝试下的。
  • 有很多路是栈道,恐高症、心脏病之类的人不适合,我有点恐高,很多时候腿都发抖,但还是坚持过来了。
  • 水要带够,特别是热的天气,普通的尖叫、脉动之类的饮料在山下普通超市大约4元一瓶,到山腰外双溪索道站涨价到10元一瓶,到日上酒店旁边的小店涨价到15元。
  • 带够补充能量的食物。在日上酒店点炒菜的话,最便宜的一盘青菜貌似48元,其他荤菜88元起。旁边的外餐40元一位,只是普通的一荤两素,康师傅泡面20元一桶。这样看来可能并没有直观的感受,我在上山前也看过类似的说法,但并不放在心上,我从山下自己带了些可充饥用的零食,到那天傍晚时随口说了句“我有点零食你们要不要吃”,然后唯一的一个卤蛋被人拿走了,唯二的两根火腿肠,还是因为我已经在吃一根了,另一根也被人拿走了,唯二的两块德芙巧克力棒也被人拿走了,以及其他一些小零食。等走回日上酒店时我已经没有足够食物,只能去买20元的泡面吃,足足背了一天的食物啊,本来是可以作为我晚饭的资料的。
  • 鞋要穿最轻便的。我一直以为爬山去穿登山鞋最合适了,于是穿了双又重又厚又防水的鞋。实际上那两天大太阳,最高气温30摄氏度,山上都是人工浇筑的台阶和栈道,根本不需要登山鞋,感觉最轻便透气的跑步鞋才是最合适的。
  • 昼夜温差大,衣服要带够保暖,又有够凉快的。
  • 在玉台看日出最出名,却不是一定要去玉台,等我从玉台下到杜鹃山庄,发现那里看日出一样很好看。
]]>
imchenwen WIP 2017-04-13T00:00:00+00:00 类库大魔王/missdeer https://blog.minidump.info/2017/04/imchenwen-wip imchenwen的进展不快,这段时间主要在做两件事:

  1. 支持VIP视频,网上有很多网站可以播放VIP视频,有收费的也有免费的,免费的可以用浏览器的开发者工具抓网络请求来分析API,大概也分两种,一种是裸奔的,直接可以用,另一种是加密的,不能直接用,我想的是用PhantomJS抓出cookie之类的再抓最终视频地址,但还没完成。
  2. 分段视频预下载。我先实现了下载到本地文件的功能,然后把本地文件路径传给播放器,但这有2个问题是:一、如果下载得比较慢,播放器读完文件播放完后就退出了,二、没有一个适用所有视频的cache值,大了就等待时间长,小了就还没开始播放就结束了。所以我打算再加一个http server给播放器,http server在响应播放器请求时会等下载了再返回数据。

Qt本身没有提供http server的API,在github上搜了搜,确实有一些用Qt实现的repo,我简单看了一下要么太重,要么功能太简单,还有就是只会跑在主线程,我主线程是要有UI的,不能用来serve http的,Qt的类要跑在工作线程还有点tricky,于是放弃了。

我知道Boost.asio有http server的示例,只要把io_service::run()跑在工作线程就可以了,代码拷过来了试了试果然可以。只是那个代码还没完全看懂,只看到它打开文件读的操作,没看到它后面继续读继续serve的操作,要再仔细看看。

引入Boost.asio很简单,只要链接Boost.system一个库就行,但在macOS上用Qt Creator直接运行程序会失败,报错:

dyld: Symbol not found: __cg_jpeg_resync_to_restart
  Referenced from: /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO
  Expected in: /usr/local/lib/libJPEG.dylib
 in /System/Library/Frameworks/ImageIO.framework/Versions/A/ImageIO

在网上搜了下遇到这个问题的人还挺多,解决方案却各不相同,有的需要修改系统里的文件,有的需要修改环境变量,都有全局性的影响,不太好。最后偶然发现有人提到macOS从某个版本起(10.12?)就把/usr/local/lib这个路径从默认搜索路径里移除了,可我的程序直接从Finder里运行是可以的,就是从Qt Creator里运行出错,于是看Qt Creator的Projects->Run->Run EnvironmentDYLD_LIBRARY_PATHDYLD_FRAMEWORK_PATH两个变量里确实都添加了/usr/local/lib,把这个路径移除,再运行就正常了。

]]>
Let's Encrypt注意事项 2017-04-12T00:00:00+00:00 类库大魔王/missdeer https://blog.minidump.info/2017/04/matters-needing-attention-about-letsencrypt 我从几个月前开始用acme.sh来自动签发Let’s Encrypt的免费证书,一两个月后,发现它没有renew成功,手动renew发现每次都是报错:

Challenge error: {"type":"urn:acme:error:malformed","detail":"Unable to update challenge :: response does not complete challenge","status": 400}

在网上随便搜了搜并没有发现有用的信息,然后给acme.sh开了个issue,照作者的说法用了DNS模式手动签发的证书不会自动renew,要用DNS API自动模式重新签发一次:

PROVIDER=cloudflare LEXICON_CLOUDFLARE_USERNAME=me@minidump.info LEXICON_CLOUDFLARE_TOKEN=11223344556677889900aabbccddeeff acme.sh --issue -d sh.yii.li -d pi.yii.li --dns dns_lexicon

如此就可以了。


对于开了80端口的,有web root的情况下,比如国外的VPS,可以不用DNS模式,可以省掉DNS那里一些看起来乱七八糟的TXT记录。但是对于像家庭宽带环境中只开443端口的情况,必须要DNS才能验证域名所有权,国内的一些主机提供商比如阿里云劫持了80端口的入流量,如果域名没有备案就会被拦截,于是也只能用DNS模式签发证书。

]]>