GnuCOBOL调用含double类型参数的C函数触发段错误问题求助
问题原因分析:COBOL调用C函数触发SIGSEGV段错误
核心问题:参数类型不匹配导致的调用约定冲突
你的问题出在COBOL传递的参数类型与C函数期望的参数类型不匹配,进而触发了内存访问错误:
C函数
func2的参数要求:func2的第二个参数是int *b,它期望接收一个指向int类型变量的内存地址,用于写入int值(0或-1)。COBOL传递的参数问题:
你在调用func2时,传递的是VAR-BD(BINARY-DOUBLE类型,即8字节浮点数)的BY REFERENCE引用。而GnuCOBOL(cobc编译器)对于浮点数类型的BY REFERENCE调用,默认不会直接传递变量的内存地址,而是传递一个**数据描述符(Data Descriptor)**的地址——这个描述符存储了变量的类型、长度等元信息,而非变量本身的内存位置。段错误的触发逻辑:
当func2把这个描述符地址当成int*去解引用(执行*b = 0)时,本质是在往不属于程序有效栈内存的区域写入数据,直接触发了SIGSEGV(非法内存访问)错误。
而func1能正常运行的原因是:你传递的VAR-BI是BINARY-SHORT SIGNED(int类型),COBOL会直接传递该变量的真实内存地址,与C函数func1的int*参数完全匹配,因此没有问题。
修复方案
修改COBOL代码,给func2传递一个int类型的变量作为第二个参数,比如复用VAR-BI:
MOVE 1.0 TO VAR-AD. MOVE -10 TO VAR-BI. MOVE ZERO TO VAR-CD. CALL "func2" USING BY VALUE VAR-AD BY REFERENCE VAR-BI RETURNING VAR-CD DISPLAY "Calling 'func2'". DISPLAY "A = ", VAR-AD, " B = ", VAR-BI, " C = ", VAR-CD
这样COBOL会传递int变量的真实地址给func2的int*参数,func2的写操作会正确修改VAR-BI的值,不会触发段错误。
额外注意事项
在COBOL与C交互时,必须保证参数类型严格对齐:
- 对于C的指针参数,COBOL必须传递对应基础类型的变量引用;
- 浮点数类型的引用传递在GnuCOBOL中默认使用描述符,若要强制传递直接地址,需要查看编译器文档调整编译选项(但不推荐,最好直接匹配类型)。
内容的提问来源于stack exchange,提问作者mysiar
相关产品推荐
相关产品推荐

