嘿哈布尔!
在这篇文章中,我们将开始讲述它的内部工作原理
为什么我们认为这很有趣? 首先,因为 1C:Enterprise 8 平台是 C++(客户端、服务器等)、JavaScript(Web 客户端)以及最近的大型(超过 10 万行代码)应用程序,并且
那么让我们开始吧。 在本文中,我们将概述该平台中使用的一些技术并概述总体情况,而不会深入研究实现。 事实上,对于许多机制来说,详细的故事需要一篇单独的文章,对于某些机制来说,需要一整本书!
首先,有必要确定基本的事情 - 1C:Enterprise 平台是什么以及它由哪些组件组成。 这个问题的答案并不那么简单,因为术语“平台”(为简洁起见,我们这样称呼它)指的是开发业务应用程序、运行时环境和管理工具的手段。 大致可以区分以下几个组成部分:
- 服务器集群
- “瘦”客户端能够通过 http 及其自己的二进制协议连接到服务器
- 用于在两层架构中工作的客户端,数据库位于硬盘驱动器或网络文件夹上
- 网络客户端
- 应用服务器管理工具
- 开发环境(称为配置器)
- iOS、Android 和 Windows Phone(移动平台 1C)的运行时环境
除 Web 客户端外,所有这些部分都是用 C++ 编写的。 此外,最近还公布了
本机应用程序
C++03 用于开发本机应用程序。 对于 Windows,使用 Microsoft Visual C++ 12(与 Windows XP 兼容的配置文件)作为编译器,对于 Linux 和 Android,使用 gcc 4.8,对于 iOS,使用 clang 5.0。 所有操作系统和编译器使用的标准库都是相同的 - STLPort。 该解决方案降低了 STL 实现特定错误的可能性。 我们目前计划迁移到 CLang 附带的 STL 实现,因为 STLPort 已停产并且与 gcc 的 C++11 启用模式不兼容。
服务器的代码库有 99% 的通用性,客户端的代码库有 95% 的通用性。 此外,即使是移动平台也使用与“大”平台相同的 C++ 代码,尽管统一的比例要低一些。
与大多数 C++ 用户一样,我们并不声称使用该语言及其库的 100% 功能。 因此,我们实际上不使用 Boost,并且语言功能之一是动态类型转换。 同时,我们积极利用:
- STL(特别是字符串、容器和算法)
- 多重继承,包括。 多重实现继承
- 模式
- 例外
- 智能指针(自定义实现)
通过使用接口的多重继承(完全抽象类),组件模型成为可能,这将在下面讨论。
组件
为了确保模块化,所有功能都分为组件,这些组件是动态库(Windows 为*.dll,Linux 为*.so)。 总共有一百五十多个组件;以下是其中一些组件的说明:
后端
包含平台元数据引擎
帐户
应用程序开发人员用来构建会计记录的对象(会计科目表和会计登记册)
BSL
嵌入式语言执行引擎
核弹
内存分配器的自定义实现
德邦8
文件数据库引擎。 一个基于ISAM的简单文件服务器数据库引擎,其中还包括一个简单的SQL处理器
数据库
包含用于实现 Windows 用户界面的基类和函数 - 窗口类、GDI 访问等。
从几个角度来看,划分为多个组件是有用的:
- 分离促进更好的设计,特别是更好的代码隔离
- 您可以通过一组组件灵活地组装不同的交付选项:
- 例如,瘦客户端安装将包含 wbase,但不会有后端
- 但在wbase服务器上,相反,不会
- 两个选项当然都包含 nuke 和 bsl
程序启动时会加载此启动选项所需的所有组件。 这对于注册 SCOM 类尤其是必要的,这将在下面讨论。
SCOM
对于较低级别的分解,使用 SCOM 系统,这是一个在思想上与 ATL 类似的库。 对于那些没有使用过 ATL 的人,我们简要列出了主要功能和特性。
对于专门设计的 SCOM 类:
- 提供工厂方法,允许您从仅知道其名称的另一个组件创建类(而不透露实现)
- 提供引用计数智能指针基础设施。 SCOM类的生命周期不需要手动监控
- 允许你找出一个对象是否实现了特定的接口,并自动将指向该对象的指针转换为指向该接口的指针
- 创建一个始终可以通过 get_service 方法等访问的服务对象。
例如,您可以在 json.dll 组件中描述用于读取 JSON 的类(例如 JSONStreamReader)。
类和实例可以从其他组件创建;它们需要在 SCOM 机器中注册:
SCOM_CLASS_ENTRY(JSONStreamReader)
该宏将描述一个特殊的静态记录器类,当组件加载到内存中时将调用该类的构造函数。
之后,您可以在另一个组件中创建它的实例:
IJSONStreamReaderPtr jsonReader = create_instance<IJSONStreamReader>(SCOM_CLSIDOF(JSONStreamReader));
为了支持服务,SCOM 提供了一个额外的、相当复杂的基础设施。 它的核心是 SCOM 进程的概念,它充当运行服务的容器(即扮演服务定位器的角色),并且还包含对本地化资源的绑定。 SCOM 进程与操作系统线程相关联。 因此,在应用程序内您可以接收如下服务:
SCOM_Process* process = core::current_process();
if (process)
return get_service<IMyService>(process);
此外,通过切换与线程相关的逻辑 (SCOM) 进程,您可以获得从信息空间的角度来看实际上独立的应用程序,并在同一线程中运行。 这就是我们的瘦客户端使用文件数据库的方式 - 在一个操作系统进程内有两个 SCOM 进程,一个与客户端关联,第二个与服务器关联。 这种方法使我们能够统一编写可在本地文件数据库和“真实”客户端服务器版本中运行的代码。 这种一致性的代价是开销,但实践表明这是值得的。
基于SCOM组件模型,实现了1C:Enterprise的业务逻辑和接口部分。
用户界面
顺便说一下接口。 我们不使用标准 Windows 控件;我们的控件直接在 Windows API 上实现。 对于 Linux 版本,已经创建了一个通过 wxWidgets 库工作的层。
控件库不依赖于 1C:Enterprise 的其他部分,并且由我们在其他几个小型内部实用程序中使用。
在 1C:Enterprise 的多年发展中,控件的外观发生了变化,但原理上的重大变化只发生过一次,即 2009 年,随着版本 8.2 的发布和“托管表单”的出现。 除了改变外观之外,表单布局的原则也发生了根本性的改变——拒绝元素的逐像素定位,转而支持元素的流动布局。 此外,在新模型中,控件不直接与域对象一起工作,而是与特殊的DTO(
这些更改使得创建复制 JavaScript 控件的 C++ 逻辑的 1C:Enterprise Web 客户端成为可能。 我们尝试保持瘦客户端和 Web 客户端之间的功能等效性。 如果这是不可能的,例如由于可用的 JavaScript API 的限制(例如,处理文件的能力非常有限),我们通常使用用 C++ 编写的浏览器扩展来实现必要的功能。 我们目前支持 Internet Explorer 和 Microsoft Edge (Windows)、Google Chrome (Windows)、Firefox(Windows 和 Linux)和 Safari (MacOS)。
此外,托管表单技术还用于为 1C 平台上的移动应用程序创建界面。 在移动设备上,控件的渲染是使用操作系统原生的技术来实现的,但对于表单布局逻辑和界面响应,则使用与“大型”1C:企业平台中相同的代码。
Linux操作系统上的1C接口
移动设备上的1C接口
其他平台1C接口
Windows操作系统上的1C接口
接口 1C - Web 客户端
开源
虽然我们不使用 Windows 下 C++ 开发人员的标准库(MFC、WinAPI 中的控件),但我们并不自己编写所有组件。 图书馆已经提到过
卷曲 用于使用 HTTP 和 FTP。OpenSSL的 用于使用加密技术并建立 TLS 连接libxml2 和 libxslt 用于 XML 解析利贝潘 用于处理邮件协议(POP3、SMTP、IMAP)拟态 解析电子邮件消息sqllite 用于存储用户日志ICU 为了国际化
这样的例子还在继续。
此外,我们使用高度修改的版本
这些库需要进行调整才能与 SCOM 组件组织模型兼容。
1C 的流行使得该平台成为对其所使用的库进行实力测试的绝佳场所。 即使是最很少使用的代码区域,各种用户和场景也会很快发现错误。 我们自己更正它们,并尝试将它们返还给库作者。 交互体验变得非常不同。
开发人员
结论
在文章中我们谈到了1C开发的几个主要方面:企业平台。 在本文的有限范围内,我们仅触及了一些我们认为有趣的方面。
可以找到各种平台机制的一般描述
您在以后的文章中会对哪些主题感兴趣?
1C移动平台是如何实现的?
Web客户端的内部结构描述?
或者您可能对为新版本选择功能、开发和测试的过程感兴趣?
写在评论中!
来源: habr.com