[英]How can I return a string allocated in C to Ada and free it in Ada?
[英]Freeing a string (allocated in Ada) in a C function using free()
我正在開發一個C-Ada綁定應用程序,我在其中使用Interfaces.C.Strings.New_String()
在Ada端分配一個新字符串。
Interfaces.C.Strings
已經有一個過程Free()
來釋放字符串的內存。 因為我需要使用Interfaces.C.Strings.Chars_Ptr
將此字符串傳遞給C函數:
如果我使用free()
函數(在stdlib.h中聲明free()
為C端的字符串釋放內存,這樣可以嗎?
如果我從C端釋放內存,這樣安全嗎?
或者我應該使用Ada方面的Interfaces.C.Strings.Free()
函數更好地釋放它?
你應該在Ada方面釋放這個字符串:
從C端調用Interfaces.C.Strings.Free
有兩個問題。
第一個是程序有Convention Ada
,所以你不能確定如何從C調用它,即使你的編譯器是GNAT因此基於GCC; 如果不編輯和重建標准庫,則無法更改此項。
第二是它的聲明是
procedure Free (Item : in out chars_ptr);
這意味着Item
通過引用傳遞( char **item
),以便它可以被清零。
您可以安排C方通過包裝調用Ada解除分配。 我的看法是,艾達語義(后Free (Item)
, Item
設置為Null_Ptr
)應該被保留,這意味着消費Ç程序被調用需要采取in out
參數,譯為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
必須在要導出的包中),帶有正文
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
看起來像
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;
(當然,規格要改為匹配)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.