I'm looking at different ways of passing string to C functions. Here is a example on 4 different way to to that and the code is tested and it works.
with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with System; use System;
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Real_Time; use Ada.Real_Time;
procedure Main is
procedure Strcpy (Target : out String; Source : in String) with Import, Convention => C, External_Name => "strcpy";
procedure Strcpy (Target : Address; Source : Address) with Import, Convention => C, External_Name => "strcpy";
procedure Strcpy (Target : out char_array; Source : in char_array) with Import, Convention => C, External_Name => "strcpy";
procedure Strcpy (Target : chars_ptr; Source : chars_ptr) with Import, Convention => C, External_Name => "strcpy";
Source : String := "Duration: " & Character (nul);
Target_String : String (Source'Range) := (others => ' ');
Target_String_Address : String (Source'Range) := (others => ' ');
Target_char_array : char_array (size_t (Source'First) .. size_t (Source'Last)) := (others => ' ');
Target_chars_ptr : chars_ptr := New_Char_Array (Target_char_array);
T : Time;
D : Time_Span;
N : constant := 100000000;
begin
T := Clock;
for I in 1..N loop
Strcpy (Target_String, Source);
end loop;
D := Clock - T;
Put_Line (Target_String & To_Duration(D)'Img);
T := Clock;
for I in 1..N loop
Strcpy (Target_String_Address'Address, Source'Address);
end loop;
D := Clock - T;
Put_Line (Target_String_Address & To_Duration(D)'Img);
T := Clock;
for I in 1..N loop
Strcpy (Target_char_array, To_C (Source));
end loop;
D := Clock - T;
Put_Line (To_Ada (Target_char_array) & To_Duration(D)'Img);
T := Clock;
for I in 1..N loop
Strcpy (Target_chars_ptr, New_String (Source));
end loop;
D := Clock - T;
Put_Line (Value (Target_chars_ptr) & To_Duration(D)'Img);
end;
Measurement
╔════════════╦════════════╦═════════════╗
║ Type ║ Conversion ║ Duration[s] ║
╠════════════╬════════════╬═════════════╣
║ String ║ ║ 0.564774366 ║
║ Address ║ ║ 0.535110315 ║
║ char_array ║ To_C ║ 2.938592901 ║
║ chars_ptr ║ New_String ║ 6.790939748 ║
╚════════════╩════════════╩═════════════╝
What method should I use with good performance in consideration?
Passing String'Address will get the best performance but should I do it?
Is there any disadvantages of any of Strcpy procedures?
Is there any benefits of any of Strcpy procedures?