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 属性提取。
我在从 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 属性提取。