c - 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 之间进行接口的经验)。
其次,假设我的理解是正确的,有没有办法解决这个问题,还是我需要采取完全不同的方法?
解决方案
谢谢大家。西蒙的回答真的很有帮助。一个问题是 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 代码所做的)。这可以编译并很好地工作。
推荐阅读
- azure - 在网络聊天中测试机器人不会返回回复。检查了许多可能的问题
- html - TypeError:无法读取未定义的属性“加入”
- python - 使用 Anaconda 在 Jupyter 笔记本中的 Scikitlearn
- c# - c# Selenium IJavaScriptExecutor 向下滚动不起作用
- python - Django 中是否有保存用户上传文件历史记录的功能?
- android - android无法解析符号R
- javascript - 在javascript中创建对象时如何保存动态键引用?
- mysql - 护照错误:无法将用户序列化到会话中
- python - 在 Matplotlib 中以对数刻度将文本旋转到一行上
- tfs - 自定义工作项(错误)并将“字段”添加到 TFS 中的顶级工作项组