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