怎么理解C语言和ABAP
本篇内容介绍了“怎么理解C语言和ABAP”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
比如像下图这种用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。报表的源代码以压缩的格式存储在表REPOclass="lazy" data-src的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。
“怎么理解C语言和ABAP”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341