使用free()在C函数中释放字符串(在Ada中分配) [英] Freeing a string (allocated in Ada) in a C function using free()

查看:132
本文介绍了使用free()在C函数中释放字符串(在Ada中分配)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个C-Ada绑定应用程序,在其中我要使用 Interfaces.C.Strings.New_String()在Ada端分配一个新字符串。

I am working on a C-Ada binding application, where I am allocating a new string in Ada side using Interfaces.C.Strings.New_String().

Interfaces.C.Strings 已经有一个过程 Free()为字符串取消分配内存。由于我需要使用 Interfaces.C.Strings.Chars_Ptr 将此字符串传递给C函数:

Interfaces.C.Strings already has a procedure Free() to deallocate the memory for string. Since I need to pass this string to a C function using Interfaces.C.Strings.Chars_Ptr:


  1. 如果我使用 free()函数(在stdlib.h中声明)为C端的字符串分配内存,可以吗?

  1. Is it OK if I deallocate memory for the string in C side using the free() function (declared in stdlib.h)?

如果我从C端释放内存是否安全?

Is it safe if I free the memory from C side?

或者我最好使用 Interfaces.C.Strings.Free()函数将其释放艾达那边?

Or I should better free it using the Interfaces.C.Strings.Free() function from Ada side?


推荐答案

调用接口有两个问题.C.Strings.Free 从C端开始。

第一个是该过程具有 Convention 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中分配)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆