gpt4 book ai didi

将 Ada 字符串转换为 C Void*

转载 作者:太空狗 更新时间:2023-10-29 17:25:50 24 4
gpt4 key购买 nike

什么是将 Ada String“转换”为 System.Adress 的好方法,这相当于将 char* 转换为void* 在 C 中。

我正在连接一个 C 库。 C 类型具有类型为 void* 的属性,库的用户通常将 C 字符串指向的地址分配为该值。例如:

struct my_type {
void* value;
};

int main() {
my_type t;
t.value = "banana";
}

我怎样才能在 Ada 中实现等价物,从 Ada 字符串开始?

我目前正在使用这种技术,但它对我来说似乎有问题。

declare
str : constant String := "banana";
data : constant char_array := To_C(str);
mine : my_type;
begin
mine.value := data(data'First)'Address;
end;

我接受任何解决方案,即使是 Ada 2012。

最佳答案

您在评论中提到您正在使用 void* “因为它应该能够获取任何内容的地址;不仅仅是一个字符串。”

那么,人们不得不问通用指针如何转换为 Ada,特别是如何利用类型化和子类型化功能。我会提出,在这种情况下,“任何事情”都无法普遍解决;也就是说,如果你想保持构造的“灵 active ”,你必须牺牲 Ada 为其类型系统提供的优势。此外,我认为按原样呈现,通常不可能可靠地用于“任何东西”。

我这样说是因为没有方法可以确定所包含的“任何东西”的长度。如果它是一个字符串,那么长度是从指向的地址开始,连续计数,直到第一个 NUL 字符 (ASCII 0)。但是,如果它不是字符串,则没有确定长度的方法(我们如何知道数组 [1,2,3] 或 OBJECT 的长度/大小)...因此我们甚至没有方法确定“任何东西”的长度。

确定长度是编写稳定/安全代码的一个重要因素,因为如果不这样做,就会导致缓冲区溢出。


但是,撇开它不谈,如果您可以提供一些关于数据的信息,无论是通过参数还是更改 my_struct,那么我们就可以使用该信息来构建更好的类型转换。 (一般来说,您对类型的了解越多越好,因为您可以用以前无法做到的方式检查数据的有效性;或者更好的是,让编译器为您检查。)

Type Data_Type is Array( Positive Range <> ) of Interfaces.Unsigned_8;
For Data_Type'Component_Size Use 8;


Function Some_Data( Stream : not null access Ada.Streams.Root_Stream_Type'Class;
Length : In Positive ) Return Data_Type is
begin
Return Result : Data_Type(1..Length) do
For Index in Result'Range loop
Interfaces.Unsigned_8'Read(Stream, Result(Index));
end Loop;
End Return;
end Some_Data;

您可以使用上面的代码生成一个 8 位无符号整数数组,其中包含流中的数据。它概述了在一般情况下您必须做的事情,但由于您正在使用 C 导入,您可以做的是稍微修改它,以便 a) 有一个 Temp 变量,它是一个类似于 Result 的数组,但是使用 For Temp'Address Use [...] 将其覆盖在 my_type.value 上,然后使用 for-loop 将其复制出来.

关于将 Ada 字符串转换为 C Void*,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9255032/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com