The use of Python ctypes to call COBOL

0 Likes
over 6 years ago

Problem

 error undefined symbol _mFsoload

 Resolution

This simple example demonstrates how well Visual COBOL can integrate with PYTHON.

It covers the core subjects of COBOL and C build, BASIC PYTHON scripting and execution.

Here is the output

Output

/home/tonyt/test/tmp >. ./doit.sh
COBDIR set to /home/products/vcdevhub22upd2preGA
cob64 -C nolist -Zv helloworld.c program1.cbl 
helloworld.c:
program1.cbl:
* Micro Focus COBOL                  V2.2 revision 002           Compiler
* Copyright (C) Micro Focus 1984-2014. All rights reserved.
* Accepted - verbose
* Accepted - nolist
* Compiling program1.cbl
* Total Messages:     0
* Data:         320     Code:          78
* Micro Focus COBOL Code Generator
* Copyright (C) Micro Focus 1984-2014. All rights reserved.
* Accepted - verbose
* Accepted - pic
* Generating program1
* Data:          88     Code:         544     Literals:          32

LD_LIBRARY_PATH     </home/products/vcdevhub22upd2preGA/lib>
LD_PRELOAD          </home/products/vcdevhub22upd2preGA/lib/libcobcrtn64.so:/home/products/vcdevhub22upd2preGA/lib/libcobrts64.so:/home/products/vcdevhub22upd2preGA/lib/libcobmisc64.so:/home/products/vcdevhub22upd2preGA/lib/libcobscreen64.so:/home/products/vcdevhub22upd2preGA/lib/libcobtrace64.so>
sys.path            <
['/home/tonyt/test/tmp', '/usr/lib64/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/lib64/python2.6/site-packages/gst-0.10', '/usr/lib64/python2.6/site-packages/gtk-2.0', '/usr/lib64/python2.6/site-packages/webkit-1.0', '/usr/lib/python2.6/site-packages', '/usr/lib/python2.6/site-packages/setuptools-0.6c11-py2.6.egg-info']
>

before c call
Started Hello World
program 1 has started
after c call

At the end of the output it shows Python calls, C then C calls COBOL, returning back to PYTHON.

The doit.sh script below shows displays from PYTHON, C and COBOL.

Here is the doit.sh

doit.sh

#
# set cobol environment
#
unset LD_LIBRARY_PATH
. /home/products/vcdevhub22upd2preGA/bin/cobsetenv
COBMODE=64
export COBMODE
#
# create c program
#
cat >helloworld.c <<EOF
/* Hello World program */

#include<stdio.h>

main()
{
    cobinit();
    printf("Started Hello World\n");
    program1();
    cobtidy();
}
EOF
#
# create cobol program
#
cat >program1.cbl <<EOF
       program-id. program1 as "program1".

       environment division.
       configuration section.

       data division.
       working-storage section.
       01 in_data        pic x(10) value "prog1 data".

       procedure division.

           display "program 1 has started"
      *     call "Program2" using in_data.
           
           goback.

       end program program1.

EOF
#
# build the .so file
#
cob -Zv helloworld.c program1.cbl
#
# create python script
#
cat >mytest.py <<EOF
import ctypes
import sys, os
print
print "LD_LIBRARY_PATH     <"   os.environ['LD_LIBRARY_PATH']   ">"
print "LD_PRELOAD          <"   os.environ['LD_PRELOAD']   ">"
print "sys.path            <" 
print sys.path 
print ">"
print
#
mylib = ctypes.CDLL("./libhelloworld.so")
print "before c call"
mylib.main()
print "after c call"
exit()
EOF
#
# run the python file
#
# get these modules loaded
#
export LD_PRELOAD=$COBDIR/lib/libcobcrtn64.so:$COBDIR/lib/libcobrts64.so:$COBDIR/lib/libcobmisc64.so:$COBDIR/lib/libcobscreen64.so:$COBDIR/lib/libcobtrace64.so
#
# run the python script
#
python mytest.py
#
# remove the LD_PRELOAD
#
unset LD_PRELOAD
#
# end
#

Create a tmp directory as in ouput above,

Enter the doit.sh code into a doit.sh script in the tmp directory,

Change the cobsetenv comand to point at your COBDIR and,

Execute the doit.sh to get it to work.

 

The key is the LD_PRELOAD for a simple c calling COBOL library

Comment List
Anonymous
  • I run it only without my environment but I had errors. SLE 11 SP2 is very poor in the library.

    The instalaltion for default do nto has a compilaer the probles is SLE a bad }very bad linux!!!

    I will discard this solution a bad idea.

  • The comments section of the Knowledge Base is the wrong place for an extended discussion. Please raise this as a new topic an appropriate MF Community forum.

    I'll be frank: It will be difficult to help you get this running if you don't have a solid understanding of basic Linux concepts. libdl.so is one such concept. So is the use of PATH and LD_LIBRARY_PATH. PATH is not used to search for shared objects, so there's no reason to be changing it. Adding random application directories (such as /Oracle/apps/...) to LD_LIBRARY_PATH is not likely to be productive; and now your script is resetting its entire value, so commenting out the unset command is pointless, and you've undone any changes that cobsetenv made to it.

  • I search for libdl.so, I had not in my path. I added to PATH and LD_LIBRARY_PATH, the error is different.

    With  which libdl.so I had 3 places when I found it.

    ./usr/lib64/libdl.so

    ./home/oracle/app/oracle/product/11.2.0/client_1/lib/stubs/libdl.so

    ./home/oracle/app/oracle/product/11.2.0/client_2/lib/stubs/libdl.so

    ./oracle/app/oracle/product/11.2.0.4/db_1/lib/stubs/libdl.so

    I add /usr/lib/libdl.so to my PATH and the fisrt Oracle path to LD_LIBRAY_PATH.

    I change the script like this: (I need *.CBL,  in UPPER  case in my configuraiton...)

    ---------------------------------------------

    #

    # set cobol environment

    #

    # unset LD_LIBRARY_PATH

    . /etc/profile.d/cobsetenv.sh

    export ORACLE_HOME=/home/oracle/app/oracle/product/11.2.0/client_2

    export PATH=$ORACLE_HOME/bin:$PATH:/lib64:/lib:/usr/lib64/

    export LD_LIBRARY_PATH=/opt/microfocus/EnterpriseDeveloper/lib:/home/oracle/app/oracle/product/11.2.0/client_2/lib:/lib64:/lib:/home/oracle/app/oracle/product/11.2.0/client_1/lib/stubs

    export COBCPY=$COBCPY:/home/equifax/copys

    export COBDIR=/opt/microfocus/EnterpriseDeveloper

    export LC_PRELOAD=/opt/microfocus/EnterpriseDeveloper/lib:/lib64

    COBMODE=64

    export COBMODE

    #

    # create c program

    #

    cat >helloworld.c <<EOF

    /* Hello World program */

    #include<stdio.h>

    #include<cobmain.h>

    #include<cobtypes.h>

    int cobinit (void);

    main()

    {

       cobinit ();

       printf("Started Hello World\n");

       program1();

       cobtidy();

    }

    EOF

    #

    # create cobol program

    #

    cat >program1.CBL <<EOF

          program-id. program1 as "program1.CBL".

          environment division.

          configuration section.

          data division.

          working-storage section.

          01 in_data        pic x(10) value "prog1 data".

          procedure division.

              display "program 1 has started"

         *     call "Program2" using in_data.

              goback.

          end program program1.

    EOF

    #

    # build the .so file

    #

    cob -Zv helloworld.c program1.CBL    

    #

    # create python script

    #

    cat >mytest.py <<EOF

    import ctypes

    import sys, os

    print

    print "LD_LIBRARY_PATH     <" + os.environ['LD_LIBRARY_PATH'] + ">"

    print "LD_PRELOAD          <" + os.environ['LD_PRELOAD'] + ">"

    print "sys.path            <"

    print sys.path

    print ">"

    print

    #

    mylib = ctypes.CDLL("./libhelloworld.so")

    print "before c call"

    mylib.main()

    print "after c call"

    exit()

    EOF

    #

    # run the python file

    #

    # get these modules loaded

    #

    export LD_PRELOAD=$COBDIR/lib/libcobcrtn64.so:$COBDIR/lib/libcobrts64.so:$COBDIR/lib/libcobmisc64.so:$COBDIR/lib/libcobscreen64.so:$COBDIR/lib/libcobtrace64.so

    #

    # run the python script

    #

    python mytest.py

    #

    # remove the LD_PRELOAD

    #

    # unset LD_PRELOAD

    #

    # end

    #

    ---------------------------------------------------

    When I run now the output is  this:

    --------------------------------------------------------

    pccdesa@DSuseBilling01:/home/equifax/python/fuentes/TEST03> ./doit.sh

    COBDIR set to /opt/microfocus/EnterpriseDeveloper

    cob64 -C nolist -Zv helloworld.c program1.CBL

    helloworld.c:

    program1.CBL:

    * Micro Focus COBOL                  V2.2 revision 002           Compiler

    * Copyright (C) Micro Focus 1984-2014. All rights reserved.

    * Accepted - verbose

    * Accepted - nolist

    * Compiling program1.CBL

        1 program-id. program1 as "program1.CBL".

    *1641-S**************************************                                **

    **    '.' in source filename or PROGRAM-ID in native code

    * Total Messages:     1

    * Unrecoverable :     0                    Severe  :     1

    * Errors        :     0                    Warnings:     0

    * Informational :     0                    Flags   :     0

    * Data:         178     Code:           0

    cob64: error(s) in compilation: program1.CBL

    LD_LIBRARY_PATH     </opt/microfocus/EnterpriseDeveloper/lib:/home/oracle/app/oracle/product/11.2.0/client_2/lib:/lib64:/lib:/home/oracle/app/oracle/product/11.2.0/client_1/lib/stubs>

    LD_PRELOAD          </opt/microfocus/EnterpriseDeveloper/lib/libcobcrtn64.so:/opt/microfocus/EnterpriseDeveloper/lib/libcobrts64.so:/opt/microfocus/EnterpriseDeveloper/lib/libcobmisc64.so:/opt/microfocus/EnterpriseDeveloper/lib/libcobscreen64.so:/opt/microfocus/EnterpriseDeveloper/lib/libcobtrace64.so>

    sys.path            <

    ['/home/equifax/python/fuentes/TEST03', '/usr/lib/python26.zip', '/usr/lib64/python2.6', '/usr/lib64/python2.6/plat-linux2', '/usr/lib64/python2.6/lib-tk', '/usr/lib64/python2.6/lib-old', '/usr/lib64/python2.6/lib-dynload', '/usr/lib64/python2.6/site-packages', '/usr/local/lib64/python2.6/site-packages']

    >

    Traceback (most recent call last):

     File "mytest.py", line 11, in <module>

       mylib = ctypes.CDLL("./libhelloworld.so")

     File "/usr/lib64/python2.6/ctypes/__init__.py", line 353, in __init__

       self._handle = _dlopen(self._name, mode)

    OSError: ./libhelloworld.so: cannot open shared object file: No such file or directory

    pccdesa@DSuseBilling01:/home/equifax/python/fuentes/TEST03>

    ---------------------------------------

    And these are the objects in the folder

    ------------------------------------------------

    pccdesa@DSuseBilling01:/home/equifax/python/fuentes/TEST03> dir

    total 76

    -r-xr--r-- 1 root    root   1400 Sep  1 10:01 cobmain.h

    -r-xr--r-- 1 pccdesa users  3694 Sep  1 10:03 cobtypes.h

    -rwxr-xr-- 1 pccdesa users  2052 Sep  4 09:02 doit.sh

    -rw-r--r-- 1 pccdesa users   202 Sep  4 09:03 helloworld.c

    -rw-r--r-- 1 pccdesa users  1744 Sep  4 09:03 helloworld.o

    drwxr-xr-x 2 pccdesa users  4096 Sep  1 10:36 lang

    drwxr-xr-x 2 pccdesa users  4096 Sep  1 10:35 lib

    -rw-r--r-- 1 pccdesa users   336 Sep  4 09:03 mytest.py

    -rw-r--r-- 1 pccdesa users   394 Sep  4 09:03 program1.CBL

    -rw-r--r-- 1 pccdesa users 39168 Sep  4 09:03 program1.idy

    pccdesa@DSuseBilling01:/home/equifax/python/fuentes/TEST03>

    -----------------------------------------------

    In my installation there was not compiler, then  I have installed gcc4.1 and I done a link symbolic to cc for python. I am new with python, but I found this sample  that could be good for my job.

    Thanks

  • "man dlopen" would answer your question "What is dlopen?".

    The programs running under the script aren't finding libdl.so, which is a standard system shared object.

    The script begins by unsetting LD_LIBRARY_PATH, which looks like a bad idea to me. I'd try it with that line removed.

  • I have many errors, for example cobint() need

    #include  <cobmain.h> and  #include cobtypes.h

    I added both to script code....

    I create folders  lib and lang

    after that I got:

    What is  dlopen ??

    Can I set this for ED in SLE 11 SP2 ?

    I had to install gcc4.1 glibc-devel cpp41.1 ...and nw this...

    /home/equifax/python/fuentes/TEST03> . ./doit.sh

    uname: symbol lookup error: /opt/microfocus/EnterpriseDeveloper/lib/libcobrts64.so: undefined symbol: dlopen

    COBDIR set to /opt/microfocus/EnterpriseDeveloper

    cat: symbol lookup error: /opt/microfocus/EnterpriseDeveloper/lib/libcobrts64.so: undefined symbol: dlopen

    cat: symbol lookup error: /opt/microfocus/EnterpriseDeveloper/lib/libcobrts64.so: undefined symbol: dlopen

    ERROR: ld.so: object '/opt/microfocus/EnterpriseDeveloper/lib/libcobcrtn64.so' from LD_PRELOAD cannot be preloaded: ignored.

    ERROR: ld.so: object '/opt/microfocus/EnterpriseDeveloper/lib/libcobrts64.so' from LD_PRELOAD cannot be preloaded: ignored.

    ERROR: ld.so: object '/opt/microfocus/EnterpriseDeveloper/lib/libcobmisc64.so' from LD_PRELOAD cannot be preloaded: ignored.

    ERROR: ld.so: object '/opt/microfocus/EnterpriseDeveloper/lib/libcobscreen64.so' from LD_PRELOAD cannot be preloaded: ignored.

    ERROR: ld.so: object '/opt/microfocus/EnterpriseDeveloper/lib/libcobtrace64.so' from LD_PRELOAD cannot be preloaded: ignored.

    /opt/microfocus/EnterpriseDeveloper/bin/cob64: symbol lookup error: /opt/microfocus/EnterpriseDeveloper/lib/libcobrts64.so: undefined symbol: dlopen

    cat: symbol lookup error: /opt/microfocus/EnterpriseDeveloper/lib/libcobrts64.so: undefined symbol: dlopen

    pccdesa@DSuseBilling01:/home/equifax/python/fuentes/TEST03> ld.so /opt/microfocus/EnterpriseDeveloper/lib/libcobcrtn64.so

    /opt/microfocus/EnterpriseDeveloper/lib/libcobcrtn64.so: symbol lookup error: /opt/microfocus/EnterpriseDeveloper/lib/libcobrts64.so: undefined symbol: dlopen

Related Discussions
Recommended