笔者之前曾经写过一篇文章:聊聊 C 语言和 ABAP,里面提到,ABAP 语言底层,包括其关键字和虚拟机(也就是 ABAP Runtime),都是基于 C/C++ 实现的。其中 ABAP 里使用最简单的 WRITE 关键字,其 C++ 的源代码就多达 2000 行以上。这个数字我是怎么知道的?答案是用本文马上要介绍的自己编写的一个小工具,找到 WRITE 实现的 C 语言源代码文件,然后看文件总行数得来的。
细心的 ABAP 开发人员可以在 ABAP 系统里,找到一些 C/C++ 的影子。
比如打开一个 ABAP 类 CL_ABAP_COMPILER 的 CHECK_FEATURE 方法,发现其实现逻辑写在了 ABAP Kernel 里,在 SAPGUI 里看到的方法只是一个壳:

ABAP 帮助文档里对这些 Kernel 方法的定义:内核方法允许直接调用用 C 或 C++ 实现的内核函数。这些内核方法取代了以前传统的 C 调用和 System Call 的概念。

再比如,我们使用 ABAP 关键字 SUBMIT,提交一个系统里并不存在的 ABAP 报表:

执行上面这个报表,发生 LOAD_PROGRAM_NOT_FOUND 运行时错误。

在 ST22 事务码里查看这个错误,在 BASIS Developer View 里,能发现 ABAP 关键字 SUBMIT,在 ABAP Kernel 里实现的源文件为 absubmit.c.
打开这个文件,里面是密密麻麻的 C 程序。在 Active Calls in SAP Kernel 里,包含了发生这个运行时错误的 C 函数调用上下文信息:

在 ABAP Control Blocks 区域,能看到这个运行时错误,是在执行虚拟机指令 SUBM 时发生的。图中这些 PERP,ENDM,SUBM 等 ABAP 虚拟机指令,可以类比成 JVM 字节码指令集。

在 ABAP 调试器里,我们通过下图的菜单项,选择 Switch to Classic Debugger,从默认的标准调试器,切换到传统调试器:

然后在 System Areas 里选择 Internal Information:

Area 字段输入 CONT 后回车,就能看到当前 ABAP 程序待执行的指令了:

前面说到,ABAP Kernel Method 取代了传统的 C 调用。所谓 C 调用,就是 ABAP 关键字 CALL. 利用这个关键字,可以在 ABAP 里执行一些系统函数。
SAP 文档明确规定,所有的 C 调用都仅能由 SAP 内部使用,不允许用来开发应用程序。所以,大家只能在 SAP 标准的框架程序看到这些 C 调用的身影。

使用下面这行 ABAP 代码,我们可以直接在 ABAP 程序里,执行 ABAP 系统安装所在的操作系统的命令:
CALL 'SYSTEM' ID 'COMMAND'
根据这行 ABAP 代码,我写了一个简单的 ABAP 报表,把这个系统函数调用封装了一下,代码如下:

演示一下这个小工具的执行效果。在报表里输入想要执行的 Linux 操作系统命令,比如 ps -aux,查看当前运行的操作系统进程列表:

Linux 操作系统进程列表打印结果如下:

使用 ls -l 命令,列出 Linux 操作系统指定文件夹下相关的 ABAP 关键字的 C 程序实现源文件列表:

列表如下,密密麻麻的都是 aba 开头的 C 和 C++ 实现文件:

双击某个文件,就能查看其源代码了:

如果大家对 ABAP 和 C/C++ 的关系感兴趣,请重温我之前发布过的这篇文章:聊聊 C 语言和 ABAP.
网友评论