首页 > 解决方案 > ada程序调用c函数有interfaces.c.size_t问题

问题描述

我一直在从事 Ada 项目,需要与 C 库 (fftw3) 交互。我使用了命令

gcc -c -fdump-ada-spec -C /usr/local/include/fftw3.h

生成初步绑定(需要一些调整)。我能够让我的代码和 fftw3_h.ads 在 gnat 中编译。但是,该程序崩溃

raised STORAGE_ERROR : fftw3_h.ads:733 object too large

当我通过 gdb 运行它时,代码在定义版本字符串的行上崩溃,

fftw_version : aliased char_array (size_t);  -- /usr/local/include/fftw3.h:457
pragma Import (C, fftw_version, "fftw_version");

我对此的理解是,Ada 试图一次为整个字符串分配空间,并将存储空间基于 size_t 的范围。但是,在这种情况下, size_t 来自 interfaces.c.size_t 定义为

type size_t is mod 2 ** System.Parameters.ptr_bits;

在 ic.ads 中,而对于 C,size_t 在 stddef.h 中定义为 unsigned long。我不确定 2**ptr_bits 有多大,但我看不出有任何理由说明 ic.ads 中 size_t 的定义应该被限制为 C 的 unsigned long 的大小。如果它比 C 的 unsigned long 长,那么我怀疑代码正在尝试创建一个使用比我拥有更多内存的数组。我尝试只使用interfaces.c.unsigned_long 而不是size_t,但Ada 不喜欢类型不匹配(我应该知道的)。

在这一点上,我有两个问题。首先,我对问题的理解是否接近(这是我第一次在 Ada 和 C 之间进行接口的经验)。

其次,假设我的理解是正确的,有没有办法解决这个问题,还是我需要采取完全不同的方法?

标签: cadafftw

解决方案


谢谢大家。西蒙的回答真的很有帮助。一个问题是 fftw_version[] 是在 fftw 的 C 代码中设置的,而不是由我设置的,我不能保证在 fftw 库中的某些东西需要它之前调用该过程(fftw3_h.ads 在我的任何代码之前详细说明) . 我还发现了 Stephen J. Sangwine 于 2004 年在网上发布的旧 FFTW_Ada 绑定。虽然我无法让他的代码正常工作,但我将他处理版本字符串的方式与 Simon 的建议结合起来,并创建了一个函数,该函数在 fftw 库中的其他内容需要时返回该字符串。

function FFTW_Version return String is
    tmp_version : aliased char_array(size_t) ;
    pragma Import(C, tmp_version, "fftw_version");
 begin
    return To_Ada(tmp_version, Trim_Nul => True) ;
 end FFTW_Version;

这给了我一些在需要时产生字符串的东西,但不对字符串的大小做出假设(FFTW_Ada 代码所做的)。这可以编译并很好地工作。


推荐阅读