编辑:我简化了代码以更好地显示情况。
任务:我有一个用 C 编写的工作套接字服务器/客户端程序。我想通过使用 Ada-C 接口来改进它。
当用户输入数学运算为 2+5、5*9、10/2 或 10-9 时获取用户输入的 C 函数
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;
}
客户端向服务器发送一个结构体,如下所述:
typedef struct
{
int number1;
int number2;
char operator;
}Operation;
ada主要程序:
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;
名为“communication_pkg”的包具有打开、关闭和读取客户端消息的功能和过程:
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;
主程序首先打开连接并等待接收来自客户端的消息。当客户端发送一个 Operation 类型的结构时,我在缓冲区中得到的内容,当客户端类型为 2+5 时,如下所述:
2 0 5 0 12331 11444 32688 0 2848 2737 32688 0 8864 64399 32767 0
缓冲区(byte_array 类型)中的第一个字节和第三个字节始终显示客户端输入的第一个和第二个整数。但是,缓冲区没有操作符(char 类型)。
如何完全获取 Operator 结构?