m 文件 dll matlab 中调用_隐藏QML模块中的QML文件

大家新年好!祝大家新的一年身体健康,百毒不侵!

鼠年开年不利,但编程学习还要继续。今天要给大家讲讲如何隐藏QML模块中的QML文件。

标题有点绕。啥叫隐藏?其实我想说的是:如何将QML模块中的QML文件编译进QML二进制插件中,而不是以源码的形式保存为单独的QML文件。(似乎更绕了……)

QML模块回顾

首先说下啥是QML模块。经常看本专栏的同学应该清楚的,所谓QML模块,至少满足下面两个条件:

  1. 一个文件夹,文件夹名和模块名一致;
  2. 文件夹内一个qmldir文件,定义了该QML模块里都有哪些内容,具体定义看官方的这个文档:Module Definition qmldir Files

qmldir中我们常用的是下面几个定义:

  1. module ExampleModule,模块名字叫啥,要和文件夹名一致;
  2. plugin <Name> [<Path>],动态链接库插件叫啥,哪个文件;
  3. <ResourceIdentifier> <InitialVersion> <File>,这个就是指定QML文件(或者js文件),例如:MyButton 1.0 MyButton.qml

除了必须的qmldir文件,常见的QML模块里包含一个动态链接库插件(Windows上是dll,Linux上是so,MacOS上是dylib),这主要是C++代码编译粗来的,和若干QML文件。很多Qt自带的QML模块都是这样,可以去Qt安装目录里的qml子目录查看。

这些QML模块里的QML文件都是以源码的形式存放的。我们用这些模块开发后的应用最终部署时也需要带上这些源码。

源码提供QML文件的优劣

QML文件以源码形式放模块中使用是有好处的:

  1. 开发时便于快速修改、测试,不需要编译;
  2. 添加新类型时,如果不涉及C++的,只需要添加QML文件、修改qmldir即可。

但它也有坏处(不然本文就没意义了不是):

  1. 发布时不便于代码保护。凭什么我们辛辛苦苦写的QML代码就这么拱手让别人看?
  2. 发布后防止QML文件损坏、被篡改。操作系统对动态链接库是有一定校验机制的,但是对于QML这样的文本文件却没有。一旦我们的QML文件被修改,或者因为各种原因损坏,很可能就造成我们的软件运行异常。这锅,我们不想背……
  3. 无法和我们的版本管理Workflow很好地衔接。DLL可以通过CMake加入版本号、Commit ID等属性信息(参见我的上一篇文章:CMake为DLL添加版本信息),但是QML文件不行。而QML又可以直接文本修改,这就会导致版本混乱。

所以我推荐软件正式发布时,要避免QML源码以源码文本的形式发布,方法就是将QML文件编译进动态链接库插件中。

如何将QML文件编译进插件?

说了这么多,真正实现起来很简单,调用一个函数的事情。

大家用C++开发QML插件时一定用过qmlRegisterType这个注册函数吧,需要在QQmlExtensionPlugin派生类中的registerTypes函数中将准备好的C++类型注册到我们的QML模块uri中。

我们一般用的函数原型是这样的:

template<typename T>
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);

比如我们写了:

class Foo : public QObject
{
    Q_OBJECT
    Q_PROPERTY(Bar *bar READ bar CONSTANT FINAL)
public:
    Foo() {}
};

那么我们就可以在registerTypes这个函数中这么注册这个类:

qmlRegisterType<Foo>(uri, 1, 0, "Foo"); 

但其实qmlRegisterType还有个形式是Qt文档中没有的:

qmlRegisterType(const QUrl &url, const char *uri, int versionMajor, int versionMinor, const char *qmlName); 

这个函数就可以用来在C++中注册我们的QML类型,效果和在qmldir中定义一样。

具体做起来有下面几步:

  1. 在QML模块工程中,建立qrc资源文件,把QML文件放入其中;
  2. 将qrc资源文件编译进动态链接库中(就是像编译exe时加入qrc文件一样);
  3. 然后调用上面的那个版本的qmlRegisterType函数。

例如qrc里我放了一个MyButton.qml文件,那么注册函数该这么调用:

qmlRegisterType(QUrl("qrc:/MyButton.qml"), "MyModule", 1, 0, "MyButton"); 

然后在我们的应用中就能够正常使用这个QML类型了,例如:

import MyModule 1.0
MyButton{
}

最终发布时,我们的QML模块将只包含一个动态链接库和一个qmldir文件。qmldir文件中只需要写明plugin是哪个插件即可,不需要任何QML文件相关内容。我们的QML源码文件是不是被隐藏了?

最后讨论

本文讲述的方法能有效避免软件发布后QML损坏、被篡改,也能起到一定的QML源码保护作用。

虽然上面这个注册函数在Qt官方文档中没有,但是Qt自身很多QML模块都在用这个函数,大家可以去qt源码中求证,所以大家可以放心大胆地使用。

另外我想说的是,源码文件虽然看不到了,但要真正像C++那样保护我们的QML源码还做不到。这个大家要注意。

究其原因,是因为虽然我们将QML编译进了动态链接库文件中,但是它还是以文本资源的形式存放其中,如果用一些资源拆包工具,例如reshacker等工具,仍然能够找到其中的QML源码。

要真正保护我们的QML源码还要借助其他工具,例如官方的Quick Compiler等。这方面的讨论,我会在以后专门用一篇文章来给大家介绍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值