【问题标题】:Setting Switches in Micro Focus COBOL using C使用 C 在 Micro Focus COBOL 中设置开关
【发布时间】:2015-11-14 11:02:55
【问题描述】:

我有一个调用 COBOL 的 C 程序。我想在调用 COBOL 程序之前设置开关。这通常使用 COBSW 环境变量来完成。

当我在 C 程序中设置 COBSW 时,它被忽略了。 当我在调用程序之前设置 COBSW 时,它被检测到了。

如何获取 C 中的 COBSW 集并让 COBOL 识别它?

以下是我尝试过的一些方法:

  1. 我删除了 cobinit() 并且程序仍然运行。这向我表明,当 C 程序启动时,cobinit 在某种程度上是自动的,它只会拾取 sh 中设置的 COBSW。

  2. 我将 cobrescanenv() 添加到程序中。

  3. 将 cobinit() 移到 cobputenv() 之前。

这是运行测试的 sh 脚本:

export C_INCLUDE_PATH=$COBDIR/include

PATH=$COBDIR/bin:$PATH

gcc -o callcobol.o -c -g -Wall -Wno-unused-variable -fPIC -Ibuild -Isrc callcobol.c

/opt/microfocus/VisualCOBOL/bin/cob -o callcobol -g callcobol.o -L/usr/local/lib -ldl -lrt -lpthread

cob -z cobsw.cbl -o TESTSW.so

unset COBSW
echo "Test ONE, COBSW not set:"
echo "We want the output to be:"
echo "SW0=ON  sw1=ON  sw2=ON  sw3=ON  sw4=ON  sw5=ON  sw6=OFF sw7=ON "
echo "Getting:"
./callcobol

#                Output:
#                        value of COBSW is: +0+1+2+3+4+5-6+7
echo ""
echo ""

export COBSW=+1+2   # This should be ignore because we are setting COBSW in the c program.
echo "Test TWO, COBSW set to ${COBSW}, but should be overlaid by putenv() in C:"
echo "We want the output to be:"
echo "SW0=ON  sw1=ON  sw2=ON  sw3=ON  sw4=ON  sw5=ON  sw6=OFF sw7=ON "
echo "Getting:"
./callcobol

这里是callcobol.c

#include <stdlib.h>
#include <stdio.h>
#include "cobcall.h"
#include "cobmain.h"
#include "cobenv.h"
PFR cobgetfuncaddr(int type, const cobchar_t *name);
int cobinit (void);

int main(int argc, char *argv[])
{
    cobchar_t *prog = (cobchar_t *) "TESTSW";
    //char *cobswval;
    const char *cobswname = "COBSW";

    cobputenv( (cobchar_t *) "COBSW=+0+1+2+3+4+5-6+7");    // out dummy computed SWITCH values for the program
    //cobswval = getenv( cobswname);
    //fprintf(stdout,"value of COBSW is: %s\n", cobswval);
    cobinit();             /* Initialize COBOL environment */
    cobrescanenv();

    PFR cobprog;

    if ((cobprog = cobgetfuncaddr(0, prog)) == NULL)
    {
        fprintf(stderr,"ERROR: could not find cobol module %s\n", (char *) prog);
    }
    else
    {
        /* Loaded */
        (*cobprog)();    /* Call it! */
    }

    cobtidy();             /* Close down COBOL environment */

    return(0);   // return a return code of zero
}

这里是cobsw.cbl

  $SET CONFIRM
  $SET IBMCOMP
  $SET CHARSET"EBCDIC"
   IDENTIFICATION DIVISION.
   PROGRAM-ID. TESTSW.
   ENVIRONMENT DIVISION.
   CONFIGURATION SECTION.
   SPECIAL-NAMES.
     SWITCH-0 IS SW0 ON IS SW_0_ON
     SWITCH-1 IS SW1 ON IS SW_1_ON
     UPSI-2 ON IS SW_2_ON
     UPSI-3 ON IS SW_3_ON
     UPSI-4 ON IS SW_4_ON
     UPSI-5 ON IS SW_5_ON
     UPSI-6 ON IS SW_6_ON
     UPSI-7 ON IS SW_7_ON.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
   DATA DIVISION.
   FILE SECTION.
   WORKING-STORAGE SECTION.
   01  rec-cnt pic 9(11) value zero.
   01  sw-out.
        02 filler     pic x(4) value "SW0=".
        02 SW0-status pic x(3).
        02 filler     pic x(5) value " sw1=".
        02 SW1-status pic x(3).
        02 filler     pic x(5) value " sw2=".
        02 SW2-status pic x(3).
        02 filler     pic x(5) value " sw3=".
        02 SW3-status pic x(3).
        02 filler     pic x(5) value " sw4=".
        02 SW4-status pic x(3).
        02 filler     pic x(5) value " sw5=".
        02 SW5-status pic x(3).
        02 filler     pic x(5) value " sw6=".
        02 SW6-status pic x(3).
        02 filler     pic x(5) value " sw7=".
        02 SW7-status pic x(3).
   01 acc-data pic x(80) value spaces.
   LINKAGE SECTION.
   PROCEDURE DIVISION.
   MAIN-PARAGRAPH.
       move "OFF" to SW0-status SW1-status SW2-status
                     SW3-status SW4-status SW5-status
                     SW6-status  SW7-status.

       IF SW_0_ON move "ON " to  SW0-status.
       IF SW_1_ON move "ON " to  SW1-status.
       IF SW_2_ON move "ON " to  SW2-status.
       IF SW_3_ON move "ON " to  SW3-status.
       IF SW_4_ON move "ON " to  SW4-status.
       IF SW_5_ON move "ON " to  SW5-status.
       IF SW_6_ON move "ON " to  SW6-status.
       IF SW_7_ON move "ON " to  SW7-status.
       display sw-out.
       EXIT PROGRAM.
   END PROGRAM TESTSW.

这是脚本输出:

Test ONE, COBSW not set:
We want the output to be:
SW0=ON  sw1=ON  sw2=ON  sw3=ON  sw4=ON  sw5=ON  sw6=OFF sw7=ON
Getting:
SW0=OFF sw1=OFF sw2=OFF sw3=OFF sw4=OFF sw5=OFF sw6=OFF sw7=OFF


Test TWO, COBSW set to +1+2, but should be overlaid by putenv() in C:
We want the output to be:
SW0=ON  sw1=ON  sw2=ON  sw3=ON  sw4=ON  sw5=ON  sw6=OFF sw7=ON
Getting:
SW0=OFF sw1=ON  sw2=ON  sw3=OFF sw4=OFF sw5=OFF sw6=OFF sw7=OFF

【问题讨论】:

  • 一般来说,您只是在为运行第一个程序而加载的环境中设置开关。您需要找到一种方法将它们从 C 导出到主环境,以便 COBOL 程序可以访问。
  • COBOL 程序运行在与 C 程序相同的进程和环境中。在这种情况下,COBOL 程序就像一个函数,而不是一个独立的程序。有了这些新信息,您能否详细说明您的陈述。或许可以告诉我们什么是“主环境”。
  • 从我阅读你的脚本的方式来看,C 实际上并没有调用 COBOL,shell 是。在典型的操作系统中,shell 包含环境。生成一个新的 shell(带有复制的环境)来运行 C 应用程序。 C 应用程序更新该环境。当它结束时,该环境被丢弃,因此启动 COBOL 的 shell 具有原始(未修改的)环境。要么 C 必须直接使用它的环境副本生成 COBOL,要么您需要将 C 版本的 shell 导出回父 shell。
  • Brian,请查看 C 代码而不是 shell 脚本,您将看到 COBOL 作为函数从 C 代码调用的位置。
  • 你能显示 callcobol 吗?也正是您正在使用的 Micro Focus COBOL 的版本和名称。

标签: cobol microfocus


【解决方案1】:

COBOL 运行时开关在进程初始化期间从环境变量 COBSW 或命令行读取一次。

不幸的是,设置 COBSW 将不起作用,因为运行时已经 阅读 COBSW。

一切都不会丢失,因为您可以使用 COBOL 中的 X"91" function 11 API 来设置开关。

【讨论】:

  • 那么 Micro Focus 提供 cobrescanenv() 的意义何在?
  • cobrescanenv 获取 DD_ 环境变量、用户设置环境变量和入口点映射环境的更改,但不幸的是 COBSW 没有。我想它可以,但它没有。
  • 该程序是使用“cob”编译的,这可确保设置 Micro Focus COBOL 运行时的环境,因此在这种情况下 cobinit() 将做的很少,因为环境已经设置好了。 cobputenv() 很受欢迎,但运行时没有注意到 COBSW 已更改为重新解析它以设置 COBOL 开关。因此我提到了 x"91" fn 11 API。
  • cobinit() 在静态链接环境中很有用。 Micro Focus 提供了一个“自包含”共享对象,它在共享对象本身被加载时初始化运行时,这不需要 cobinit()。
  • 谢谢。满足我。你能用这些东西更新你的答案吗?所以它是来自各种 Micro Focus 文档的“事物”的应用程序,我猜它们不会相互合作:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-29
  • 1970-01-01
  • 2021-01-22
  • 1970-01-01
  • 2011-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多