这个公众号之前的文章,分享的都是Jerry和SAP成都研究院的同事在工作中学到的一些知识和感受。而今天这篇文章,写作的由来是因为最近我又参与了SAP成都数字创新空间应聘者的面试,和一些朋友聊了一些关于用不同的编程语言写Hello World程序的话题,突然才发现,自己从2007年毕业之后,再没有使用过C语言进行编程了。因此想做一个简单的回忆。对C语言不感兴趣的ABAP开发顾问,可以直接跳到本文讲ABAP的章节。
为什么这篇文章要把C语言和ABAP放在一起讲,而不是别的语言比如Java和ABAP呢?因为ABAP语言底层是基于C/C++实现的,包括其关键字(比如最简单的关键字WRITE的C++实现有2千多行)和虚拟机(ABAP Runtime)。SAP内部的一群计算机科学家们发明了ABAP这门伟大的语言,由它实现的各种SAP应用帮助了全球超过180个国家和地区的客户们更好地运行其业务。
通过Google我们能搜索到一些关于这些SAP计算机科学家们的介绍,比如这个链接:
比如像下图这种用kernel module修饰的sc_km_check_feature_2, 以及每一个ABAP关键字,其C语言的实现代码在SAP内部的Netweaver系统可以查看到,但是在客户系统上,则是以二进制目标文件的形式存储,无法查看源代码。
本文的目的是希望通过C语言和ABAP编译过程的一些介绍,加深ABAP顾问们对这门语言的理解。
用C语言写个Hello World程序,另存为study.c:
用命令行gcc ./study.c --verbose进行编译,参数verbose可供我们查看编译明细。上述命令行在我的Ubuntu系统上产生一串长长的输出:
我们可以一步步分析。首先用参数 -E查看预处理生成的目标文件study.i:
gcc -E study.c -o study.i
可以看到源代码文件只有78字节,编译预处理后生成的输出文件有17116字节。
为什么膨胀了这么多?原因是因为我源代码文件的第一行,#include<stdio.h>被预处理器替换成了stdio.h的实际内容,而stdio.h里如果又存在#include其他文件的声明,这个替换过程会递归执行。因此直到study.i的末尾部分,我们才能看到在study.c里书写的源代码部分。
源代码文件study.c里的第一行语句 #include<stdio.h>, 请大家记住,后面讲ABAP还会提到。
用命令行gcc -S可以查看study.c编译后生成的汇编代码:
看到这些pushq, popq, %rbp,Jerry不由得想起本科汇编程序设计专业课上,我和寝室其他兄弟坐在教室最后一排看体坛周报的时光。
工作十多年后,Jerry不得不承认,当时本科开设的计算机专业课,像数据结构,操作系统,计算机组成原理,编译原理,汇编程序设计,计算机图形学这些都是有用的,工作后,公司不可能再给你时间去学习这些基础理论知识了。
虽然汇编程序设计这门课Jerry当初没有好好学,但至少教材我是妥善保存了的,以防哪天公司的工作安排需要让我把十多年前在学校学的东西重新又捡起来。
下面我们来聊聊ABAP。
SAP note 1230076 ”Generation of ABAP loads: Tips for the analysis” 介绍了一个工具程序:RSDEPEND。这个note提到,一个即便看起来最简单的ABAP Hello World报表,其实也依赖于许多标准的Repository对象,这些依赖我们假定称其为A,B,C。假设A,B,C其中有任何一个有改动产生,比如A是一个include程序,里面使用到了一个DDIC结构,在某个时刻,系统导入了一个传输请求(Transport Request), 里面包含了针对这个DDIC结构的更改,那么此时这个最简单的Hello World报表的load就成为了obsolete状态。在重新执行该报表之前,ABAP Runtime(中文译成ABAP运行时)会自动做一个load invalidation操作,生成一个最新版本的load。
什么是ABAP load?看ABAP help里的官方定义:
“In the ABAP environment, a load describes a binary representation of a repository object which is optimized for fast access, in the memory or on the database.”
翻译成中文:ABAP load是Repository对象的二进制表现形式,针对ABAP环境的快速访问而做过特别优化,可以存储在数据库表中或者加载于内存里。
我们用一个实际的例子来理解ABAP报表激活和运行时发生的事情。
创建一张非常简单的透明表ZLOADTEST:
写一个简单的报表,命名为ZTESTLOAD。报表的源代码以压缩的格式存储在表REPOSRC的DATA字段里。
测试报表的源代码很简单,把表里的数据全部读取出来:
激活这个简单的报表(是的,在ABAP世界里,我们习惯说激活,而不是编译)。激活后生成的ABAP load存储在表REPOLOAD的字段LDATA和QDATA里。
这两个字段存储的内容就是前面ABAP help提到的ABAP load在数据库表中的存储形式。
菜单Goto->Navigate to->Switch to Classic Debugger:
Goto->System Areas->Internal Information:
在System Area区域输入CONT,就能在下图的NAME列看到ABAP load里包含的指令。当然同开源的JVM不同,JVM字节码指令集在网上能够查到,而这些ABAP load的指令是SAP internal的,因此不能在这里做解释。
然后执行前面提到的工具报表RSDEPEND, 输入参数program name = ZTESTLOAD, 得到结果,其中测试报表的ABAP Load时间戳为07:21:02, 这个报表依赖的标准Include有:
-
<REPINI>
-
<SYSINI>
-
<SYSSEL>
-
DB__SSEL
由此看出,每一个标准的ABAP报表都自动包含了这些include。如果开发人员显式地再包含其中任意一个,会遇到语法错误: Module %_PF_STATUS is already defined as a OUTPUT module.
大家觉得这个<REPINI>是不是很像前文C语言部分提到的#include<stdio.h>?
下面我们再做几轮测试。
测试1
修改透明表的描述信息,然后重新激活透明表。
执行RSDEPEND, 可以看到只有透明表的Last Changed字段发生了变化,ABAP Time Stamp和Screen Time Stamp都不变,这是我们期望的结果,因为我们只是修改了透明表的描述信息,并未修改结构。
再次执行测试报表ZTESTLOAD, 用RSDEPEND检测,发现测试报表的ABAP Load时间戳没有发生变化,这说明:即使依赖的透明表的描述信息发生变化,使用了该透明表的ABAP报表不需要重新编译,因为透明表描述信息不需要在报表执行期使用。
测试2
给透明表增加新的一列,再次激活。
此时通过RSDEPEND发现,透明表的三个时间戳全部发生了变化,如下图蓝色矩形框所示。然而测试报表ABAP Load本身的时间戳仍然未变,这也是合理的,因为我们给透明表里增加了新的列后,还未执行测试报表。
再次执行ZTESTLOAD后,这次发现它的ABAP Load已经被自动invalidate了,时间戳从07:21:02变成了07:36:02。
这也解释了一个现象:有的朋友们观察到,当系统刚升完级后,或者有一批新的传输请求导入到系统后,第一次使用SAP应用时,系统响应速度很慢。原因其实通过前文的两个测试已经说明了:系统在花费时间去做相关ABAP Load invalidation。在应用依赖的这些Load invalidation没有结束之前,系统无法响应用户请求。
为了避免用户在第一次使用应用时长时间等待,可以使用事务码SGEN预先进行Load invalidation。SGEN详细的使用方法可以参考下面这篇文章
希望这篇文章能给那些想了解ABAP语言底层一些实现细节的顾问朋友们有所帮助。
更多阅读
要获取更多Jerry的原创文章,请关注公众号"汪子熙":
相关推荐
ABAP 4.7引入了类和对象的概念,支持继承、封装和多态性,这使得代码可维护性和复用性大大提升。 5. 功能模块和库: 功能模块是预定义的程序单元,可以被其他程序调用。ABAP库则包含一组相关功能模块,用于特定的...
2. **生成Proxy代码**:在目标系统中,使用SE80事务码,通过“生成ABAP Proxy”功能,输入源系统的服务接口信息,自动生成对应的ABAP Proxy类和相关代码。 3. **编译与激活**:生成的Proxy代码需要在目标系统中进行...
在ABAP编程中,加密和解密是两个关键的安全操作,用于保护敏感数据不被未经授权的用户访问。本文将深入探讨ABAP环境下的加密和解密技术,以及如何在实际应用中实施这些技术。 首先,我们需要理解加密的基本原理。...
作为ABAP的学习资料,"ABAP学习资料abap"包含了针对初学者和进阶者的全面教程,旨在帮助用户在三个月内掌握ABAP的基础到高级知识。 文档“ABAP三月通.doc”很可能包含以下关键知识点: 1. **ABAP概述**:介绍ABAP...
abap tips abap tips abap tips abap tips abap tips
ABAP - Keyword Documentation This documentation describes the syntax and meaning of the keywords of the ABAP language and its object-oriented part ABAP Objects. Alongside this, language frameworks ...
SAP ABAP 开发环境和开发工具介绍 SAP ABAP 开发环境和开发工具是 SAP 系统中最重要的组件之一,它提供了一个强大的开发平台,允许开发者创建、测试和部署 ABAP 程序。ABAP 是 SAP 系统中的主要编程语言,用于开发...
在ABAP中,ALV(ABAP List Viewer)是一种强大的工具,用于显示和处理数据表。ALV提供了一种标准化的方式来展示表格数据,包括排序、过滤、分组和自定义列等功能,极大地简化了用户界面的开发。 标题“abap-ALV.rar...
ABAP开发规范和命名规则是IBM提供的一套开发标准和命名惯例,为ABAP开发者提供了详细的开发指南和命名规则,以确保开发的程序代码质量和可读性。本文将对ABAP开发规范和命名规则进行详细的解释和说明。 一、文档...
- ABAP与数据库交互:学习使用ABAP SQL(Open SQL和Native SQL)与数据库进行高效交互。 - RFC(Remote Function Call):理解如何通过RFC调用其他系统的服务或函数。 通过这些文档的学习,你可以逐步建立起对...
标题和描述所涉及的知识点主要集中在ABAP语言在SAP系统中对数据库的操作和管理。由于这部分内容比较专业,我将尽量详细地阐述ABAP(Advanced Business Application Programming)逻辑数据库和数据库操作的概念和用法...
随着学习的深入,会涉及ABAP的数据存储,如数据库表(内部表和透明表)的创建和操作,以及如何使用ABAP的数据访问语法来与数据库交互。接着,将学习到ABAP报表编程,包括编写动态SQL和使用ABAP的Report程序来生成...
"abap xlsx2 demo 程序"是一个示例项目,旨在展示如何在SAP系统中读取和写入Excel文件。在这个程序中,开发者可能使用了特定的库或者自定义开发的函数来实现与Excel的交互。 首先,要理解ABAP如何处理.xlsx文件,...
在本文中,我们将详细介绍 ABAP OLE 颜色代码的使用方法和应用场景。 ABAP OLE 颜色代码的应用场景非常广泛,例如: * 设置控件的背景颜色和文字颜色 * 创建自定义的颜色主题 * 实现视觉效果,如阴影、渐变等 * ...
1. 数据处理:ABAP提供了大量的内建函数用于数据操作,如字符串处理(CONCATENATE、SUBSTRING等)、数值计算(ADD、SUBTRACT等)、日期和时间操作(DATE_TO_ABAP_DATE、TIME_TO_ABAP_TIME等)。这些函数使得在ABAP...
这个“ABAP中文帮助文档”包含了对ABAP基础、报表编写以及事务处理的详细指南,对于学习和理解ABAP编程至关重要。 在第一部分“ABAP/4基础”中,你将学习到: 1. **ABAP简介**:了解ABAP的历史、作用以及它在SAP...
首先,ABAP Query 允许用户添加自定义字段和计算字段。这些字段的值可以来源于其他表格或通过复杂的计算公式得出。例如,你可以从一个关联的表中提取信息,或者创建一个计算字段来展示两个数值字段的总和或比率。...
ABAP语言的核心是支持结构化程序设计,它与传统的第三代编程语言(如C语言和Pascal)有显著的区别。ABAP语言属于第四代编程语言(4GL),其语法和结构更接近于Visual Basic或JAVA。 2. ABAP基础: 在创建简单的...
SAP ABAP(Advanced Business Application Programming)是SAP公司推出的一种高级业务应用编程语言,用于开发在SAP R/3和SAP NetWeaver平台上的应用程序。这些电子书提供了全面的资源,帮助学习者深入理解并掌握SAP ...
ABAP WorkBench是SAP系统中的核心开发环境,它为ABAP(Advanced Business Application Programming)程序员提供了全面的工具集,用于开发、测试和维护SAP应用。在深入探讨ABAP WorkBench的知识点之前,我们需要理解...