Ada 向 c 发送字节缓冲区

Ada sending byte buffer to c

我在从 ada 连接到 C 时遇到问题。特别是我有这个 ada 声明:

type Byte is mod 256; pragma Convention (C, Byte);
type ByteStream is array (Interfaces.C.size_t range <>) of Byte;
    pragma Convention (C, ByteStream);
type VoidPointer is access all ByteStream;
type ByteBuffer is
    record
        data : VoidPointer;
        size : Interfaces.C.size_t;
    end record;
pragma Convention (C, ByteBuffer);
procedure Free is new Ada.Unchecked_Deallocation (ByteStream, VoidPointer);

和这个 C 声明:

struct ByteBuffer {
    unsigned char *data;
    size_t size;
};

和这个 ada 导入:

function My_Function (
    data : in ByteBuffer)
    return Interfaces.C.int;
pragma Import (C, My_Function, "my_function");

和这个 C 声明:

int my_function(struct ByteBuffer data);

然而,当我调试我的代码时,我发现 ada 端的大小(在一个示例中)为 110,但 c 端的大小为 0x7fffffffe750。为什么我的 size_t 被损坏了? (注意:数据本身也被破坏了,但希望修复一个就能修复另一个)。

Ada 中的 in 参数可以使用引用或复制,但它 compiler/structure 取决于大小。

要强制双方都使用指针(这里最简单的做法)你可以这样做:

Ada 方面:

function My_Function (
    data : access ByteBuffer)
    return Interfaces.C.int;
pragma Import (C, My_Function, "my_function");

C端:

int my_function(const struct ByteBuffer *data);

由于ByteBuffer是一个约束数组,另一个信息传递:边界是一个指针(整个指针是一个"fat"指针)。你可以 "skip" 通过这样做在 C 端:

struct ByteBuffer {
    unsigned char *data;
    void *skipit;  // ignore this value
    size_t size;
};

强制Ada通过拷贝传递,可以在类型声明后使用pragma Convention(C_Pass_By_Copy,ByteBuffer)(Ada端)

Ada 无界字符串具有依赖于编译器的数据映射。在我使用的那个中,我检查了它是否以说明字符串大小的内容(如标签)开头,然后是 "normal" 字节数组。当您将缓冲区从 C 传递给 Ada 时,最后一个将从 C 数组的第一个元素中获取无界数组的长度。 我不知道你为什么需要你的例子,但如果我想你要指向已经创建的数据的数组,你可以将 ByteStream 声明为一个固定长度的数组(可以说和你的最大大小一样大)因为你要使用 "size" 参数管理实际尺寸。 换句话说,你在 ada 中拥有 ByteBuffer 记录的 "size" 参数是没有意义的,因为它进入指向的无界字符串结构并且可以使用 'Length 属性提取。