EDIT: I simplified my codes to better show the situation.
TASK: I have a working socket server/client program written in C. I want to improve it by using Ada-C interfacing.
C function that gets the user input when the user enters a mathematical operation as 2+5, 5*9, 10/2 or 10-9
int read_message(void *buffer, int size, int timeout)
{
//Recevie
int n = recv(newfd, buffer, size, 0);
if(n == -1)
{
perror("Can not read message");
return -1;
}
return 1;
}
The client sends a struct to the server as stated below:
typedef struct
{
int number1;
int number2;
char operator;
}Operation;
Ada main procedure:
with Ada.Text_IO, communication_pkg, Ada.Exceptions, Interfaces.C;
use Ada.Text_IO, communication_pkg;
procedure Main is
package C_pkg renames communication_pkg;
begin
Put_Line(Integer'Image(C_pkg.open_communication));
Put_Line("Server is Open");
C_pkg.read_message;
exception
when Event: Open_Error =>
Put_Line("Can not open connection");
New_Line;
Put_Line(Ada.Exceptions.Exception_Name(Event));
New_Line;
Put_Line(Ada.Exceptions.Exception_Message(Event));
New_Line;
Put_Line(Ada.Exceptions.Exception_Information(Event));
when Event: Close_Error =>
Put_Line("Can not close connection");
New_Line;
Put_Line(Ada.Exceptions.Exception_Name(Event));
New_Line;
Put_Line(Ada.Exceptions.Exception_Message(Event));
New_Line;
Put_Line(Ada.Exceptions.Exception_Information(Event));
when Event: Can_not_read_error =>
Put_Line("Can not read");
New_Line;
Put_Line(Ada.Exceptions.Exception_Name(Event));
New_Line;
Put_Line(Ada.Exceptions.Exception_Message(Event));
New_Line;
Put_Line(Ada.Exceptions.Exception_Information(Event));
when Event: Read_timeout_error =>
Put_Line("Read timeout");
New_Line;
Put_Line(Ada.Exceptions.Exception_Name(Event));
New_Line;
Put_Line(Ada.Exceptions.Exception_Message(Event));
New_Line;
Put_Line(Ada.Exceptions.Exception_Information(Event));
when Event: others =>
Put_Line("Something else went wrong");
New_Line;
Put_Line(Ada.Exceptions.Exception_Name(Event));
New_Line;
Put_Line(Ada.Exceptions.Exception_Message(Event));
New_Line;
Put_Line(Ada.Exceptions.Exception_Information(Event));
end Main;
Package called "communication_pkg" that has functions and procedures which opens, closes and reads client message:
with Interfaces.C, Ada.Unchecked_COnversion, Ada.Text_IO;
use Interfaces.C, Ada.Text_IO;
with System;
package body Communication_pkg is
package C renames Interfaces.C;
function open return Integer;
pragma Interface(C, open);
pragma Interface_Name(open, "open");
function close return Integer;
pragma Interface(C, close);
pragma Interface_Name(close, "close_connection");
function read(buffer: in System.Address; size : in Integer; timeout: in Integer) return Integer;
pragma Interface(C,read);
pragma Interface_Name(read, "read_message");
function open_communication return Integer is
connection_status : Integer;
begin
connection_status := open;
if (connection_status = -1) then
raise Open_Error;
end if;
return connection_status;
end open_communication;
function close_communication return Integer is
connection_status : Integer;
begin
connection_status := close;
if(connection_status = -1) then
raise Close_Error;
end if;
return connection_status;
end close_communication;
procedure read_message is
size : Integer:=9;
timeout : Integer:=1;
read_message_status : Integer;
type byte is range 0..255;
type byte_array is array (Integer range 0..15) of byte;
--buffer : System.Address
buffer : byte_array;
begin
Put_Line("read message in");
read_message_status:=read(buffer'Address, size, timeout);
Put_Line(Integer'Image(read_message_status));
if(read_message_status = -1) then
raise Can_not_read_error;
elsif(read_message_status = -2) then
raise Read_timeout_error;
end if;
Put_Line("read message out");
for i in 0..15 loop
Put_Line(byte'Image(buffer(i)));
end loop;
end;
end Communication_pkg;
The main procedure first opens the connection and waits for receiving a message from the client. When the client sends a struct of type Operation, what I get in the buffer, when 2+5 is type by the client, is something as stated below:
2 0 5 0 12331 11444 32688 0 2848 2737 32688 0 8864 64399 32767 0
The first byte and the third byte in the buffer(of type byte_array) always show the first and second integer entered by the client. However, the buffer does not have the operator(of type char).
How can I get the Operator struct completely?
Unchecked_Conversion
from aSystem.Address
to aByte_Array
is almost certainly not what you want. This takes an address (which is either 4 or 8 bytes on this system) and reinterprets the bits of the address as aByte_Array
, which is 256 bytes. (2) We don't know what anOperation
is. (3)for i in 0..8
executes the loop nine times.i
will take every value 0, 1, ..., 7, 8. Is that what you want? (4) We may need to see just how the Ada program is calling the C function, including anyImport
/Export
aspects/pragmas you're using. - ajbcommunication_pkg
to justCommunications
. We can all see that it's a package! - Simon Wright