FPC and Apache Modules/ru

From Lazarus wiki
Revision as of 19:03, 27 March 2010 by Sergey (talk | contribs)
Jump to navigationJump to search

Как связующее звено было создано (How the bindings were created)

The translated headers follow some simple guidelines. First all translated declarations remain at the exact same position as they were on the .h files, unless there is a incompatibility and they have to be moved. This is to make it easier to compare the .h files with the pascal translation and find possible mistakes on translation. Second, most files become include files, and some units are created to hold them. In particular, one unit was created for each apache library (httpd, apr, aprutil and apriconv).

Трансляционные заголовки выполняют несколько простых нормативов. Во-первых, все трансляционные объявления оставляют точно ту же позицию как они были в .h файлах, если они не несовместимы и должны быть перемещены. Это так, чтобы сделать более простым сравнение .h файлов с pascal трансляцией и нахождение возможных ошибок при трансляции. Во-вторых, множество файлов становятся include файлами и несколько unit'ов создается, чтобы владеть ими.

The translation was all done manually with the help of "Replace All" from the Lazarus IDE. This is because automatic translators cannot deal with the heavy use of macros by apache headers, and passing the c preprocessor produces a code that is unrecognizably different from the original headers.

Трансляция была вся полностью сделана вручную с помощью "Replace All" в Lazarus IDE......

The Apache headers heavily rely on macros to work. In fact, almost every single declaration is a macro. Below are some of the most common macros and appropriate translations:


1 - AP_DECLARE

AP_DECLARE(void) ap_add_version_component(apr_pool_t *pconf, const char *component);


procedure ap_add_version_component(pconf: Papr_pool_t; const component: PChar);
 {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
 external LibHTTPD name LibNamePrefix + 'ap_add_version_component' + LibSuff8;

The AP_DECLARE macro says that the calling convention for the function is stdcall on Windows and cdecl on other operating systems, so we need an IFDEF for this. It also says that the function name will have a prefix and a suffix on Windows. The prefix is "_" and the suffix is "@N", where N is a number multiple of 4. Typically, the number is 4 times the number of parameters on the function, but there are some exceptions. To find out possible conflicts on the function names, a software to list all exported functions of a DLL was created, and later transformed into a Lazarus example called Libview.

2 - AP_DECLARE_NONSTD

AP_DECLARE_NONSTD(const char *) ap_set_string_slot(cmd_parms *cmd, 
                                                   void *struct_ptr,
                                                   const char *arg);


function ap_set_string_slot(cmd: Pcmd_parms; struct_ptr: Pointer; const arg: PChar): PChar;
 cdecl; external LibHTTPD name 'ap_set_string_slot';

This is the same as AP_DECLARE, but the calling convention is cdecl and no suffix or prefix is present on the function name.

3 - Other combinations

APR_DECLARE_NONSTD(int) apr_file_printf(apr_file_t *fptr, 
                                        const char *format, ...)


function apr_file_printf(fptr: Papr_file_t; const format: PChar;
 others: array of const): Integer;
 cdecl; external LibAPR name 'apr_file_printf';

Another possible combination are macros starting with APR. AP means libhttpd, APR is libapr, APU is libaprutil and API is for libapriconv. Also notice that this function has a variable number of parameters, that in pascal is represented by an array of const.

4 - AP_DECLARE_HOOK

AP_DECLARE_HOOK(int,pre_connection,(conn_rec *c, void *csd))

type
  ap_HOOK_pre_connection_t = function (c: Pconn_rec; csd: Pointer): Integer; cdecl;

procedure ap_hook_pre_connection(pf: ap_HOOK_pre_connection_t; const aszPre: PPChar;
 const aszSucc: PPChar; nOrder: Integer);
 {$IFDEF WINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
 external LibHTTPD name LibNamePrefix + 'ap_hook_pre_connection' + LibSuff16;

The hooks use one of the most strange declarations possible. All hook are represent a function like ap_hook_pre_connection, with the same 4 parameters, and no return. The difference between them is the first parameter, that has a different function type in each hook function.

AP_DECLARE_HOOK macro receives 3 parameters. The first is the return type of the hook function type. The second plus the prefix ap_hook_ form the name of the function, and the third are the parameters of the hook function.