Hi All,
Could anyone help me with some samples of writing socket program with libevent, or is there any adapter/wrapper already exists for freepascal?
Thanks!
Xiangrong

Mailing lists / fpc-pascal / 2016-01
4 messages · 4 people · –
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
Hi All,
Could anyone help me with some samples of writing socket program with libevent, or is there any adapter/wrapper already exists for freepascal?
Thanks!
Xiangrong
I used libevent in a C project, but you can use it easily with Pascal (FPC and/or Delphi). For example, I did this small draft [1] that compiles in Free Pascal (it is just a helloworld fast HTTP server), using the libevent 2.0.5:
=== begin code ===
program helloworld;
{$mode objfpc}{$H+}
uses
{$IFDEF MSWINDOWS}
WinSock2,
{$ENDIF}
ctypes;
const
EV_LIB_NAME = {$IFDEF MSWINDOWS}'libevent-2-0-5'{$ELSE}'event'{$ENDIF};
{$IFDEF FPC}
{$PACKRECORDS C}
{$ENDIF}
const
HTTP_OK = 200;
type
pcchar = PAnsiChar;
evbuffer = packed record
end;
Pevbuffer = ^evbuffer;
event_base = packed record
end;
Pevent_base = ^event_base;
evhttp = packed record
end;
Pevhttp = ^evhttp;
evhttp_request = packed record
end;
Pevhttp_request = ^evhttp_request;
evkeyvalq = packed record
end;
Pevkeyvalq = ^evkeyvalq;
evhttp_set_gencb_cb = procedure(p1: Pevhttp_request; p2: Pointer); cdecl;
function evbuffer_add_printf(buf: Pevbuffer; fmt: pcchar): cint; cdecl;
varargs; external EV_LIB_NAME name 'evbuffer_add_printf';
function event_init: pevent_base; cdecl; external EV_LIB_NAME name
'event_init';
function event_dispatch: cint; cdecl; external EV_LIB_NAME name
'event_dispatch';
function evhttp_start(address: pcchar; port: cshort): pevhttp; cdecl;
external EV_LIB_NAME name 'evhttp_start';
function evbuffer_new: Pevbuffer; cdecl; external EV_LIB_NAME name
'evbuffer_new';
procedure evhttp_set_gencb(http: Pevhttp; cb: evhttp_set_gencb_cb; arg:
Pointer); cdecl; external EV_LIB_NAME name 'evhttp_set_gencb';
function evhttp_add_header(headers: Pevkeyvalq; key: pcchar; value:
pcchar): cint; cdecl; external EV_LIB_NAME name 'evhttp_add_header';
function evhttp_request_get_output_headers(req: Pevhttp_request):
Pevkeyvalq; cdecl; external EV_LIB_NAME name
'evhttp_request_get_output_headers';
procedure evhttp_send_reply_start(req: Pevhttp_request; code: cint;
reason: pcchar); cdecl; external EV_LIB_NAME name 'evhttp_send_reply_start';
procedure evhttp_send_reply_chunk(req: Pevhttp_request; databuf:
Pevbuffer); cdecl; external EV_LIB_NAME name 'evhttp_send_reply_chunk';
procedure evhttp_send_reply_end(req: Pevhttp_request); cdecl; external
EV_LIB_NAME name 'evhttp_send_reply_end';
procedure evbuffer_free(buf: Pevbuffer); cdecl; external EV_LIB_NAME name
'evbuffer_free';
procedure generic_request_handler(req: Pevhttp_request; arg: Pointer);
cdecl;
var
returnbuffer: Pevbuffer;
begin
returnbuffer := evbuffer_new;
evhttp_add_header(evhttp_request_get_output_headers(req),
'Content-Type', 'text/html');
evhttp_add_header(evhttp_request_get_output_headers(req), 'Connection',
'keep-alive');
evbuffer_add_printf(returnbuffer, '<html><head><title>Hello
world</title></head><body>Hello world</body></html>');
evhttp_send_reply_start(req, HTTP_OK, 'OK');
// Chuncked reply
evhttp_send_reply_chunk(req, returnbuffer);
evhttp_send_reply_end(req);
evbuffer_free(returnbuffer);
end;
var
http_port: cshort = 8080;
http_addr: pcchar = '0.0.0.0';
http_server: Pevhttp = nil;
{$IFDEF MSWINDOWS}
wsa_data: WSAData;
{$ENDIF}
begin
{$IFDEF MSWINDOWS}
WSAStartup($0201, wsa_data);
{$ENDIF}
event_init;
http_server := evhttp_start(http_addr, http_port);
evhttp_set_gencb(http_server, @generic_request_handler, nil); // Callback
on event
WriteLn('Server started on port ', http_port);
WriteLn('Press [ENTER] to exit ...');
event_dispatch;
end.=== end code ===
Is this a purely Windows thing or is it portable to all environments supported by FreePascal, like Linux on ARM etc?
There seems to be conditionals for MSWINDOWS but nothing else....
It works on all unix (including raspberry) platforms as well.
Michael.