forked from garybernhardt/selecta
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Simple example that shows how to write a php extension that uses a Rust function.
- Loading branch information
Showing
3 changed files
with
109 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,33 @@ | |||
PHP_ARG_WITH(score, | |||
[Whether to enable the "score" extension], | |||
[ --enable-score Enable "score" extension support]) | |||
|
|||
if test "$PHP_SCORE" != "no"; then | |||
|
|||
dnl Explicitly define the location of the library. | |||
dnl Production extensions should use the example from ext_skel on how to | |||
dnl properly check common library directories for the existence of your | |||
dnl libs. | |||
SCORE_LIB_DIR=/usr/local/lib | |||
|
|||
dnl This is the proper way to check for the existance of a library. But... | |||
dnl this creates a simple program that expects a .h file that will define | |||
dnl our functions. Rust does not provide that, so it fails. There is | |||
dnl probably some autotools magic I can do to make this work, but alas. | |||
dnl PHP_CHECK_LIBRARY(score, score_ext, | |||
dnl [ | |||
dnl PHP_ADD_LIBRARY_WITH_PATH(score, $SCORE_LIB_DIR, SCORE_SHARED_LIBADD) | |||
dnl AC_DEFINE(HAVE_SCORE, 1, [Whether you have score]) | |||
dnl ],[ | |||
dnl AC_MSG_ERROR([ext_score function not found in libscore]) | |||
dnl ],[ | |||
dnl -L$SCORE_LIB_DIR -R$SCORE_LIB_DIR | |||
dnl ]) | |||
|
|||
dnl Just blindly assume our libscore.so library exists | |||
PHP_ADD_LIBRARY_WITH_PATH(score, $SCORE_LIB_DIR, SCORE_SHARED_LIBADD) | |||
-L$SCORE_LIB_DIR -R$SCORE_LIB_DIR | |||
|
|||
PHP_SUBST(SCORE_SHARED_LIBADD) | |||
PHP_NEW_EXTENSION(score, score.c, $ext_shared) | |||
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,20 @@ | |||
#ifndef PHP_SCORE_H | |||
|
|||
#define PHP_SCORE_H | |||
|
|||
#define PHP_SCORE_EXTNAME "score" | |||
#define PHP_SCORE_EXTVER "1.0" | |||
|
|||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
|
|||
#include "php.h" | |||
|
|||
extern zend_module_entry score_module_entry; | |||
#define phpext_score_ptr &score_module_entry | |||
|
|||
// Because Rust does not provide a .h file to include | |||
extern double ext_score(char *, char *); | |||
|
|||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,56 @@ | |||
#include "php_score.h" | |||
|
|||
PHP_FUNCTION(score) | |||
{ | |||
char *choice; | |||
int choice_len; | |||
char *query; | |||
int query_len; | |||
|
|||
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &choice, &choice_len, &query, &query_len) == FAILURE) { | |||
return; | |||
} | |||
|
|||
// PHP does not terminate strings with a nul byte. | |||
char *choice_c_str = emalloc(choice_len + 1); | |||
strncpy(choice_c_str, choice, choice_len); | |||
choice_c_str[choice_len] = '\0'; | |||
|
|||
char *query_c_str = emalloc(query_len + 1); | |||
strncpy(query_c_str, query, query_len); | |||
query_c_str[query_len] = '\0'; | |||
|
|||
double s = ext_score(choice_c_str, query_c_str); | |||
|
|||
efree(choice_c_str); | |||
efree(query_c_str); | |||
|
|||
RETURN_DOUBLE(s); | |||
} | |||
|
|||
ZEND_BEGIN_ARG_INFO_EX(arginfo_score, 0, 0, 1) | |||
ZEND_ARG_INFO(0, choice) | |||
ZEND_ARG_INFO(0, query) | |||
ZEND_END_ARG_INFO() | |||
|
|||
zend_function_entry php_score_functions[] = { | |||
PHP_FE(score, arginfo_score) | |||
{NULL, NULL, NULL} /* must be the last line */ | |||
}; | |||
|
|||
zend_module_entry score_module_entry = { | |||
STANDARD_MODULE_HEADER, | |||
PHP_SCORE_EXTNAME, | |||
php_score_functions, | |||
NULL, /* minit */ | |||
NULL, /* mshutdown */ | |||
NULL, /* rinit */ | |||
NULL, /* rshutdown */ | |||
NULL, /* minfo */ | |||
PHP_SCORE_EXTVER, | |||
STANDARD_MODULE_PROPERTIES | |||
}; | |||
|
|||
#ifdef COMPILE_DL_SCORE | |||
ZEND_GET_MODULE(score) | |||
#endif |