Forum Webscript.Ru
Программирование => PHP => Тема начата: Nat от 13 Августа 2002, 18:10:26
-
Такая проблема :(
Есть библиотека (написана в Delphi), которая экспортирует процедуры. В качестве параметров передаются строки PChar.
Как вызвать эти процедуры в PHP?
Знаю, что есть такие понятия как extension и функция dl(), но не более. Буду благодарна за помощь.
-
Почитай:
http://www.php.net/manual/en/zend.structure.php#zend.structure.module
Тут описано как строить модули расширения
-
Nat
Там не dl() а get_module()
Советую взять исходники для винды и изучить их
-
Спасибо за ответ :-)
исходники для винды
- какие исходники, не совсем поняла;
По-поводу статьи по ссылке, я действительно тону... Мне бы что-нибудь более целое в качестве примера. Там вероятно много хорошего написано по англицки, но... как-то картина не вырисовывается. Сложно, или мой англ совсем плох.
-
Nat
исходники
Исходные коды.
более целое
Кусок кода модуля ftp:
#include "php.h"
#if HAVE_FTP
#include
#include
#include
#ifdef HAVE_UNISTD_H
#include
#endif
#include
#include
#include
#ifdef PHP_WIN32
#include
#else
#ifdef HAVE_SYS_TYPES_H
#include
#endif
...
/*
реализация функции ftp_open
*/
ftp_open(const char *host, short port, long timeout_sec)
{
ftpbuf_t *ftp;
int size;
struct timeval tv;
/* alloc the ftp structure */
ftp = calloc(1, sizeof(*ftp));
if (ftp == NULL) {
perror("calloc");
return NULL;
}
tv.tv_sec = timeout_sec;
tv.tv_usec = 0;
ftp->fd = php_hostconnect(host, (unsigned short) (port ? port : 21), SOCK_STREAM, &tv);
if (ftp->fd == -1) {
goto bail;
}
/* Default Settings */
ftp->timeout_sec = timeout_sec;
ftp->async = 0;
size = sizeof(ftp->localaddr);
memset(&ftp->localaddr, 0, size);
if (getsockname(ftp->fd, (struct sockaddr*) &ftp->localaddr, &size) == -1) {
perror("getsockname");
goto bail;
}
if (!ftp_getresp(ftp) || ftp->resp != 220) {
goto bail;
}
return ftp;
bail:
if (ftp->fd != -1)
closesocket(ftp->fd);
free(ftp);
return NULL;
}
/* }}} */
...
Заголовочный файл (ftp.h):
#ifndef FTP_H
#define FTP_H
#include "php_network.h"
#include
#ifdef HAVE_NETINET_IN_H
#include
#endif
#define FTP_DEFAULT_TIMEOUT 90
#define FTP_DEFAULT_AUTOSEEK 1
#define PHP_FTP_FAILED 0
#define PHP_FTP_FINISHED 1
#define PHP_FTP_MOREDATA 2
/* XXX this should be configurable at runtime XXX */
#define FTP_BUFSIZE 4096
typedef enum ftptype {
FTPTYPE_ASCII,
FTPTYPE_IMAGE
} ftptype_t;
typedef struct databuf
{
int listener; /* listener socket */
int fd; /* data connection */
ftptype_t type; /* transfer type */
char buf[FTP_BUFSIZE]; /* data buffer */
} databuf_t;
typedef struct ftpbuf
{
int fd; /* control connection */
php_sockaddr_storage localaddr; /* local address */
int resp; /* last response code */
char inbuf[FTP_BUFSIZE]; /* last response text */
char *extra; /* extra characters */
int extralen; /* number of extra chars */
char outbuf[FTP_BUFSIZE]; /* command output buffer */
char *pwd; /* cached pwd */
char *syst; /* cached system type */
ftptype_t type; /* current transfer type */
int pasv; /* 0=off; 1=pasv; 2=ready */
php_sockaddr_storage pasvaddr; /* passive mode address */
long timeout_sec; /* User configureable timeout (seconds) */
int autoseek; /* User configureable autoseek flag */
int async; /* asyncronous transfer in progress */
databuf_t *data; /* Data connection for asyncrounous transfers */
php_stream *stream; /* output stream for asyncrounous transfers */
int lastch; /* last char of previous call */
int direction; /* recv = 0 / send = 1 */
int closestream;/* close or not close stream */
} ftpbuf_t;
/* open a FTP connection, returns ftpbuf (NULL on error)
* port is the ftp port in network byte order, or 0 for the default
*/
ftpbuf_t* ftp_open(const char *host, short port, long timeout_sec);
/* quits from the ftp session (it still needs to be closed)
* return true on success, false on error
*/
int ftp_quit(ftpbuf_t *ftp);
/* frees up any cached data held in the ftp buffer */
void ftp_gc(ftpbuf_t *ftp);
/* close the FTP connection and return NULL */
ftpbuf_t* ftp_close(ftpbuf_t *ftp);
/* logs into the FTP server, returns true on success, false on error */
int ftp_login(ftpbuf_t *ftp, const char *user, const char *pass);
/* reinitializes the connection, returns true on success, false on error */
int ftp_reinit(ftpbuf_t *ftp);
/* returns the remote system type (NULL on error) */
const char* ftp_syst(ftpbuf_t *ftp);
/* returns the present working directory (NULL on error) */
const char* ftp_pwd(ftpbuf_t *ftp);
/* exec a command [special features], return true on success, false on error */
int ftp_exec(ftpbuf_t *ftp, const char *cmd);
/* changes directories, return true on success, false on error */
int ftp_chdir(ftpbuf_t *ftp, const char *dir);
/* changes to parent directory, return true on success, false on error */
int ftp_cdup(ftpbuf_t *ftp);
/* creates a directory, return the directory name on success, NULL on error.
* the return value must be freed
*/
char* ftp_mkdir(ftpbuf_t *ftp, const char *dir);
/* removes a directory, return true on success, false on error */
int ftp_rmdir(ftpbuf_t *ftp, const char *dir);
/* returns a NULL-terminated array of filenames in the given path
* or NULL on error. the return array must be freed (but don\'t
* free the array elements)
*/
char** ftp_nlist(ftpbuf_t *ftp, const char *path);
/* returns a NULL-terminated array of lines returned by the ftp
* LIST command for the given path or NULL on error. the return
* array must be freed (but don\'t
* free the array elements)
*/
char** ftp_list(ftpbuf_t *ftp, const char *path, int recursive);
/* switches passive mode on or off
* returns true on success, false on error
*/
int ftp_pasv(ftpbuf_t *ftp, int pasv);
/* retrieves a file and saves its contents to outfp
* returns true on success, false on error
*/
int ftp_get(ftpbuf_t *ftp, php_stream *outstream, const char *path,
ftptype_t type, int resumepos);
/* stores the data from a file, socket, or process as a file on the remote server
* returns true on success, false on error
*/
int ftp_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos);
/* returns the size of the given file, or -1 on error */
int ftp_size(ftpbuf_t *ftp, const char *path);
/* returns the last modified time of the given file, or -1 on error */
time_t ftp_mdtm(ftpbuf_t *ftp, const char *path);
/* renames a file on the server */
int ftp_rename(ftpbuf_t *ftp, const char *src, const char *dest);
/* deletes the file from the server */
int ftp_delete(ftpbuf_t *ftp, const char *path);
/* sends a SITE command to the server */
int ftp_site(ftpbuf_t *ftp, const char *cmd);
/* retrieves part of a file and saves its contents to outfp
* returns true on success, false on error
*/
int ftp_async_get(ftpbuf_t *ftp, php_stream *outstream, const char *path,
ftptype_t type, int resumepos);
/* stores the data from a file, socket, or process as a file on the remote server
* returns true on success, false on error
*/
int ftp_async_put(ftpbuf_t *ftp, const char *path, php_stream *instream, ftptype_t type, int startpos);
/* continues a previous async_(f)get command
*/
int ftp_async_continue_read(ftpbuf_t *ftp);
/* continues a previous async_(f)put command
*/
int ftp_async_continue_write(ftpbuf_t *ftp);
#endif
сам модуль находится в файлах hp_ftp.c php_ftp.h
Вот как обявляются функции:
* {{{ proto resource ftp_connect(string host [, int port [, int timeout)]])
Opens a FTP stream */
PHP_FUNCTION(ftp_connect)
{
ftpbuf_t *ftp;
char *host;
int host_len, port = 0;
long timeout_sec = FTP_DEFAULT_TIMEOUT;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &host, &host_len, &port, &timeout_sec) == FAILURE) {
return;
}
if (timeout_sec <= 0) {
php_error(E_WARNING, "%s(): Timeout has to be greater than 0",
get_active_function_name(TSRMLS_C));
RETURN_FALSE;
}
/* connect */
ftp = ftp_open(host, (short)port, timeout_sec);
if (ftp == NULL) {
RETURN_FALSE;
}
/* autoseek for resuming */
ftp->autoseek = FTP_DEFAULT_AUTOSEEK;
ZEND_REGISTER_RESOURCE(return_value, ftp, le_ftpbuf);
}
/* }}} */
/* {{{ proto bool ftp_login(resource stream, string username, string password)
Logs into the FTP server */
PHP_FUNCTION(ftp_login)
{
zval *z_ftp;
ftpbuf_t *ftp;
char *user, *pass;
int user_len, pass_len;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rss", &z_ftp, &user, &user_len, &pass, &pass_len) == FAILURE) {
return;
}
ZEND_FETCH_RESOURCE(ftp, ftpbuf_t*, &z_ftp, -1, le_ftpbuf_name, le_ftpbuf);
/* log in */
if (!ftp_login(ftp, user, pass)) {
php_error(E_WARNING, "%s(): %s", get_active_function_name(TSRMLS_C), ftp->inbuf);
RETURN_FALSE;
}
RETURN_TRUE;
}
/* }}} */
Если вкратце - в одном файле находятся функции, реализующие более или менее универсальную функциональность, а в другом (php_ftp.c) непосредственно експортируемые функции.
В лучшем случае тебе придется сделать еще одну библиотеку, которая будет надстройкой над уже существующей
Поясняю:
-
Имеется библиотека, написанная на Delphi (далее идет псевдокод библиотеки):
...
{ Абсолютно бессмысленная функция }
function LibraryFunction(inputValue : integer) : PChar;
var
resultat : string;
begin
resultat := IntToStr(inputValue);
LibraryFunction := str2pchar(resrultat);
end;
...
Интерфейсная библиотека будет выглядеть примерно так (опять же сильно упрощенный псевдокод):
...
PHP_FUNCTION(lib_func)
{
char * tmp;
int integer = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rs", &integer) == FAILURE) {
return;
}
tmp = LibraryFunction(integer);
RETURN_STRING(tmp, 1);
}
...
Примерно так...
-
Не сочтите за наглость и назойливость,
но допустим написала интерфейсную библиотеку php_lib.c (там просто прототипы ф-ций PHP_FUNCTION..., как я поняла).
Куда должны быть помещены файл с самой библиотекой Delphi.dll и php_lib.c ? Или php_lib.c надо скопилировать, а только потом куда-то положить? (просто в С++ окромя значка == ничего не знаю, а значит шансы спасения утопающего близки к 0)
И после всего этого теоретически я могу просто обратиться из кода PHP к любой ф-ции, обявленной в прототипах, по ее имени без указания ее источника (имени библ-ки)?
-
Nat
Ты должна откомпилить php_lib.c - положить ее в папку extensions и проиписать ее в разделе extensions файла php.ini
Соответственно, если используется внешняя библиотека (Delphi.dll)- то ее надо положить либо в туже папку, что и php_lib.dll или в системную папку (проще в туже папку)
И после всего этого теоретически
Да сможешь. Учитывая, то, что я написал...
-
Однозначно ХОРОШИЙ человек без всяких или :-)
Спасибо!
-
Пожалста.
:)