问题描述
我正在开发一个C-Ada绑定应用程序,在其中我要使用 code>,因此即使您的编译器是GNAT&,您也无法确定如何从C调用它因此基于GCC;并且您不能在不编辑和重建标准库的情况下进行更改。
The first is that the procedure has Convention Ada, so you can’t be sure of how to call it from C, even if your compiler is GNAT & therefore GCC-based; and you can’t change this without editing and rebuilding the standard library.
第二个是其声明为
procedure Free (Item : in out chars_ptr);
这意味着 Item 是通过引用传递的( char ** item ),使其可以为空。
which means that Item is passed by reference (char **item) so that it can be nulled.
您可以安排C端调用包装Ada释放。我的观点是,Ada语义(在 Free(Item), Item 之后)设置为 Null_Ptr )应该保留,这意味着要调用的消费C过程需要采用 in out 参数,翻译为 char ** 。
You could arrange for the C side to call the Ada deallocation with wrapping. My view is that the Ada semantics (after Free (Item), Item is set to Null_Ptr) should be preserved, which means that the consuming C procedure to be called needs to take an in out parameter, translated as char **.
with Interfaces.C.Strings; package String_Freeing is procedure C_Consumer (Item : in out Interfaces.C.Strings.chars_ptr) with Import, Convention => C, External_Name => "c_consumer"; procedure Free_Wrapper (Item : in out Interfaces.C.Strings.chars_ptr) with Export, Convention => C, External_Name => "free_ada_string"; end String_Freeing;
( Free_Wrapper 必须放在软件包中带有正文
(Free_Wrapper has to be in a package to be exported), with body
package body String_Freeing is procedure Free_Wrapper (Item : in out Interfaces.C.Strings.chars_ptr) is begin Interfaces.C.Strings.Free (Item); end Free_Wrapper; end String_Freeing;
和测试程序
with Interfaces.C.Strings; with String_Freeing; use String_Freeing; procedure Test_String_Freeing is Str : Interfaces.C.Strings.chars_ptr; use type Interfaces.C.Strings.chars_ptr; begin Str := Interfaces.C.Strings.New_String ("hello world."); C_Consumer (Str); pragma Assert (Str = Interfaces.C.Strings.Null_Ptr, "str not nulled"); end Test_String_Freeing;
其中C的一面可能是
#include <stdio.h> extern void free_ada_string(char **item); void c_consumer(char **item) { printf("%s\n", *item); free_ada_string(item); }
如果您愿意将悬空指针留在Ada一侧,则可以将字符串作为 in ( char * )参数传递,这将使 Free_Wrapper 像
If you’re willing to leave dangling pointers on the Ada side, you could pass the string as an in (char *) parameter, which would make Free_Wrapper look like
package body String_Freeing is procedure Free_Wrapper (Item : Interfaces.C.Strings.chars_ptr) is Dummy : Interfaces.C.Strings.chars_ptr := Item; begin Interfaces.C.Strings.Free (Dummy); end Free_Wrapper; end String_Freeing;
(当然要更改为匹配值)。
(spec to be changed to match, of course).
这篇关于使用free()在C函数中释放字符串(在Ada中分配)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!