GnuCOBOL调用外部C函数遇编译报错及链接问题,求解决方案
COBOL调用外部C库的链接与调用问题解决
问题背景
近期测试COBOL调用外部C库时,遇到编译语法错误和链接时找不到C函数的问题,以下是具体场景和解决方法。
C库代码与编译
编写的测试C库代码:
// testlib.c #include <stdio.h> void CFUNC() { printf("This is a C function.\n"); }
编译为静态库的命令:
gcc -c -o testlib.o testlib.c ar rcs libout.a testlib.o
错误的COBOL实现与报错
最初的COBOL源码:
IDENTIFICATION DIVISION. PROGRAM-ID. CallCFunction. PROCEDURE DIVISION. EXTERNAL "CFUNC". CALL "CFUNC" STOP RUN.
使用以下命令编译时:
cobc -x -free -o cobollink cobollink.cbl -L/path/to/lib -lout
出现语法错误:
cobollink.cbl:6: error: syntax error, unexpected EXTERNAL
去掉EXTERNAL后编译通过,但链接时提示找不到CFUNC函数。
正确的实现步骤
1. 修正COBOL语法错误
EXTERNAL不能单独作为语句使用,需将其附加在CALL语句后,正确的COBOL代码:
IDENTIFICATION DIVISION. PROGRAM-ID. CallCFunction. PROCEDURE DIVISION. CALL "CFUNC" EXTERNAL STOP RUN.
2. 解决函数符号匹配问题
GnuCOBOL默认会将CALL指定的函数名转换为小写+下划线前缀的格式(例如"CFUNC"会被转换为_cfunc),而你的C函数符号是大写的CFUNC,因此需要通过以下两种方式之一解决:
方式一:调整C函数名匹配GnuCOBOL的默认规则
修改C库代码,将函数名改为_cfunc:
// testlib.c #include <stdio.h> void _cfunc() { printf("This is a C function.\n"); }
重新编译C库后,直接使用原编译命令即可链接成功。
方式二:禁用GnuCOBOL的函数名转换
使用-fno-underscore编译选项,让GnuCOBOL直接使用指定的函数名查找符号:
cobc -x -free -fno-underscore -o cobollink cobollink.cbl -L/path/to/lib -lout
此方式无需修改C库代码,直接使用原大写函数名即可匹配。
环境信息
$cobc -V cobc (GnuCOBOL) 4.0-early-dev.0 Copyright (C) 2020 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html> This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Written by Keisuke Nishida, Roger While, Ron Norman, Simon Sobisch, Edward Hart Built Sep 14 2021 19:23:38 Packaged Jun 06 2020 20:56:36 UTC C version "11.2.0"
系统:UBUNTU 22.04
内容的提问来源于stack exchange,提问作者Prince 2 lu
相关产品推荐
相关产品推荐

