Ada向c发送字节缓冲区

时间:2016-10-17 16:13:19

标签: c ada

我遇到了从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被破坏了? (注意:数据本身也会受损,但希望修复一个会修复另一个)。

2 个答案:

答案 0 :(得分:3)

Ada中的in参数可以使用引用或复制,但它依赖于编译器/结构大小。

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

在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是一个约束数组,另一个信息通过:作为指针的边界(整个指针是&#34; fat&#34;指针)。你可以&#34;跳过&#34;它在C方面这样做:

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

要强制Ada通过副本,您可以在类型声明后使用pragma Convention(C_Pass_By_Copy,ByteBuffer)(Ada方面)

答案 1 :(得分:0)

Ada无界字符串具有编译器相关的数据映射。在我使用的那个中,我已经检查过它的开头是一些东西(比如一个标签),它说明了字符串的大小,然后是“普通”的字节数组。当您将缓冲区从C传递给Ada时,最后一个将从C数组的第一个元素中获取无界数组的长度。 我不知道为什么你需要你的例子,但是如果我想你要指出已经创建的数据的数组,你可以将ByteStream声明为一个固定的legth数组(比如你的最大大小),因为你要去使用“size”参数管理实际大小。 换句话说,没有任何意义,你可以在ada中使用ByteBuffer记录的“size”参数,因为它进入指向的无界字符串结构,并且可以使用'Length atribute。

进行提取。