我如何 return 在 C 中分配给 Ada 的字符串并在 Ada 中释放它?

How can I return a string allocated in C to Ada and free it in Ada?

这是的倒数。

我在 C 函数(特别是 cJSON 库)中分配了一个字符串,我想 return 作为输出参数给 Ada 调用者,并从 Ada 中释放该字符串。

C 界面如下所示:

typedef struct
{
    int f1;
    int f2;
    // ...
} A;

int Dump_Record(const A& rec, char** outstr);

Dump_Record 函数将 outstr 设置为由 cJSON_Print 编辑的值 return,它通过 malloc.

分配一个字符串

应如何指定 Ada 绑定以及如何检索输出字符串并在 Ada 中正确解除分配它?

下面显示了 return 将 char ** 作为 return 类型和输出 Ada 参数的 Ada、C 和 GPR 文件。

with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C.Strings; use Interfaces.C.Strings;

procedure Str is
   function Get_Str return chars_ptr with
     Import => True,
     Convention => C,
     External_Name => "get_str";

   procedure Get_Str (Str : in out chars_ptr) with
     Import => True,
     Convention => C,
     External_Name => "get_str2";

   Str  : chars_ptr := Get_Str;
   Str2 : chars_ptr := Null_Ptr;
begin
   Get_Str (Str2);

   Put ("==> " & Value (Str));
   Put ("==> " & Value (Str2));

   Free (Str);
   Free (Str2);
end Str;
#include <malloc.h>
#include <string.h>

const char *str  = "Hello, Ada\n";
const char *str2 = "This is another C string!\n";

// As a return type.
const char *get_str (void) {
    char *ptr = malloc (strlen (str) + 1);

    strcpy (ptr, str);

    return ptr;
}

// As a return / out parameter.
void get_str2 (char **ptr) {
    *ptr = malloc (strlen (str2) + 1);

    strcpy (*ptr, str2);
}
project Str is
   for Languages use ("C", "Ada");
   for Source_Dirs use (".");
   for Exec_Dir use ".";
   for Main use ("str.adb");
end Str;

gprbuild -P str编译。

所以要在 Ada 中实现您的功能:

package C renames Interfaces.C;

type A is
   record
      F1, F2 : C.int;
   end record with
     Convention => C;

   function Dump_Record (Rec : aliased A; Out_Str : out chars_ptr) return C.int with
     Import => True,
     Convention => C,
     External_Name => "Dump_Record";

显然,Rec 参数需要别名,以便编译器知道它是 C 中的引用,并且不会在其他地方重新分配它,即辅助堆栈。