Skip to content

Commit

Permalink
Glue Rust to php
Browse files Browse the repository at this point in the history
Simple example that shows how to write a php extension that uses a Rust
function.
  • Loading branch information
hjr3 committed Aug 3, 2015
1 parent 710138f commit b48de0a
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 0 deletions.
33 changes: 33 additions & 0 deletions php-ext/config.m4
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
20 changes: 20 additions & 0 deletions php-ext/php_score.h
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
56 changes: 56 additions & 0 deletions php-ext/score.c
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

0 comments on commit b48de0a

Please sign in to comment.