363d1bb20f
This change is mostly for FB internal organizational reasons. Building is not effected beyond the fact that the target now lands in hphp/hhvm/hhvm rather than src/hhvm/hhvm.
174 linhas
7.3 KiB
Plaintext
174 linhas
7.3 KiB
Plaintext
|
|
<h2>How to Use HipHop Compiled Libraries in Python</h2>
|
|
|
|
1. Building a library for Python
|
|
|
|
When an HipHop project is compiled with --format=lib-ffi, a SWIG .i file is
|
|
generated to wrap all the top-level PHP functions, located in directory
|
|
<b>output/ffi</b>. In <b>output</b>, run "make" with
|
|
<b>hphp/src/ffi/python.mk</b>, then a python wrapper and a corresponding
|
|
shared library will be created in directory <b>output/ffi/python</b>.
|
|
|
|
For example, if your HipHop project is named phplib, after the above steps,
|
|
you will get a Python wrapper phplib.py and a shared library _phplib.so, both
|
|
in <b>output/ffi/python</b>. To use it in python, just do
|
|
|
|
LD_PRELOAD="libstdc++.so.6" python
|
|
>>> import phplib
|
|
|
|
Then you can start using functions implemented in HipHop. Note that LD_PRELOAD
|
|
is needed due to some swig related problem explained here:
|
|
|
|
http://stackoverflow.com/questions/2778193/segfault-during-cxa-allocate-exception-in-swig-wrapped-library
|
|
|
|
|
|
2. Using HipHop functions in Python
|
|
|
|
(1) hphpStart()
|
|
|
|
This function initializes the HipHop environment, including all static
|
|
variables. It only needs to be called ONCE before calling any HipHop functions.
|
|
For example,
|
|
|
|
phplib.hphpStart();
|
|
|
|
(2) hphpStartSession() and hphpFinishSession()
|
|
|
|
The first function starts an HipHop session, within which HipHop functions are
|
|
called, and HipHop objects live. It also returns a session handle (a pointer to
|
|
the underlying HphpSession object) that becomes the first parameter of every
|
|
HipHop function call. It also initializes global HipHop variables.
|
|
|
|
The second function takes the session handle as its parameter, and finishes
|
|
the session by destrying all the references to HipHop objects that have been
|
|
created in the session. Therefore, after hphpFinishSession(), they Python
|
|
program should NOT try to use any values generated by the HipHop library.
|
|
|
|
Continue with the phplib example:
|
|
|
|
s = phplib.hphpStartSession();
|
|
# calling HipHop functions
|
|
phplib.hphpFinishSession(s);
|
|
|
|
Each HipHop object created inside an HipHop session s will live until the time
|
|
hphpFinishSession(s) is called. Therefore, a session should not create too
|
|
many HipHop objects. After all, a session is not meant to run for a long time.
|
|
A Python program, after calling hphpStart(), may create an arbitrary number of
|
|
HipHop sessions, but two HipHop sessions must NOT overlap, at least not in the
|
|
same thread.
|
|
|
|
(3) Calling HipHop functions
|
|
|
|
The HipHop session needs to keep track of every HipHop object created during
|
|
the session in order to properly destroy them in the end. Therefore, every
|
|
HipHop function wrapped in Python takes an extra parameter for the session
|
|
handle. For example, if there is an HipHop function f() implemented in phplib,
|
|
in Python, it is called as (s is the session handle):
|
|
|
|
phplib.f(s);
|
|
|
|
(4) Passing values between HipHop and Python
|
|
|
|
Each HipHop value is represented as a Variant pointer, which is essentially
|
|
opaque in Python. The HipHop value contained in a Variant could be one of the
|
|
following 7 types: null, boolean, int (64-bit), double, string, array, or
|
|
object. The library defines constants to represent each type: TypeNull,
|
|
TypeBoolean, TypeInt, TypeDouble, TypeString, TypeArray, TypeObject. For
|
|
example, to test whether an HipHop value v is an integer or not, one can use:
|
|
|
|
if phplib.hphpGetType(v) == phplib.TypeInt:
|
|
...
|
|
|
|
There are also several helper functions that can be used to create HipHop
|
|
values, or to retrieve primitive values from an HipHop Variant. For example:
|
|
|
|
b = phplib.hphpBoolean(s, True); # b now contains an HipHop boolean
|
|
|
|
str = phplib.hphpString(s, "hello"); # creates a string in HipHop
|
|
print phplib.hphpGetString(s, str); # retrieves the string back to Python
|
|
|
|
a = phplib.hphpArray(s); # a contains an empty HipHop array
|
|
phplib.hphpSet(s, a, b, str); # array (true => "hello")
|
|
str2 = phplib.hphpGet(s, a, b); # str2 contains HipHop string "hello"
|
|
|
|
There is also an hphpAppend function to add a value to the end of an HipHop
|
|
array, phplib.hphpAppend(s, a, b) in Python is the same as a[] = b in PHP.
|
|
|
|
Each Python value needs to be wrapped before being passed to HipHop, and each
|
|
value returned by HipHop needs to be unwrapped before Python can access the
|
|
value. Please see <b>hphp/src/ffi/swig/swig.i</b> for the definitions of all
|
|
the helper functions.
|
|
|
|
(5) Invoking funtions or files dynamically
|
|
|
|
There are also helper functions for dynamically invoking a top-level HipHop
|
|
function or including a PHP file (which must be part of the compiled library
|
|
as well).
|
|
|
|
phplib.hphpInvoke(s, "f", arr); # invokes the HipHop function f,
|
|
# HipHop array arr contains the
|
|
# arguments
|
|
phplib.hphpIncludeFile(s, "lib/users.php"); # includes a compiled PHP file
|
|
|
|
Moreover, all the built-in functions of PHP are also available through dynamic
|
|
invocation.
|
|
|
|
(6) Iteration through an HipHop array
|
|
|
|
One can iterate through an HipHop array (a set of key-value pairs) with
|
|
built-in helper functions: hphpIterBegin(), hphpIterAdvance(), and
|
|
hphpIterValid(). For example,
|
|
|
|
iter = phplib.hphpIterBegin(s, arr); # iter is an opaque pointer
|
|
# to the underlying array
|
|
# iterator
|
|
while phplib.hphpIterValid(s, iter):
|
|
key = phplib.hphpIterGetKey(s, arr, iter); # gets the key
|
|
value = phplib.hphpIterGetValue(s, arr, iter); # gets the value
|
|
# neither of the two getter
|
|
# functions moves the
|
|
# iterator
|
|
...
|
|
iter = phplib.hphpIterAdvance(s, arr, iter); # advances the iterator
|
|
|
|
There are also some other helper functions that help manipulate arrays.
|
|
For example,
|
|
|
|
a = phplib.hphpArray(s);
|
|
...
|
|
len = phplib.hphpCount(s, a); # gets the size of the array
|
|
key = ...
|
|
b = phplib.hphpIsset(s, a, key); # checks whether a[key] is set, returns
|
|
# a boolean value in Python (not an HipHop
|
|
# variant)
|
|
|
|
phplib.hphpUnset(s, a, key); # unsets a[key]
|
|
|
|
(7) Accessing object variables
|
|
|
|
Object variables are accessed through helper functions hphpSetField(),
|
|
hphpGetField(), hphpIssetField(), and hphpUnsetField(). They are generally
|
|
similar to their array counterparts. However, fields are named with Python
|
|
strings, but array keys are HipHop variants. For example,
|
|
|
|
a = phplib.hphpNewObject(s, "A", args); # creates an object of type A
|
|
v = phplib.hphpGetField(s, a, "f"); # gets a->f
|
|
v2 = ...
|
|
phplib.hphpSetField(s, a, "f", v2); # a->f = v2
|
|
phplib.hphpIssetField(s, a, "f"); # should return TRUE now
|
|
phplib.hphpUnsetField(s, a, "f"); # unsets the field f
|
|
|
|
(8) Manipulating global variables
|
|
|
|
Global variables are accessed with helper functions hphpGetGlobal() and
|
|
hphpSetGlobal(). For example,
|
|
|
|
a = phplib.hphpGetGlobal(s, "_SERVER"); # gets a copy of the global variable
|
|
# $_SERVER
|
|
phplib.hphpSet(s, a, "SRC", "/"); # $_SERVER['SRC'] NOT updated yet
|
|
phplib.hphpSetGlobal(s, "_SERVER", a); # $_SERVER updated
|
|
|
|
Note that the value obtained with hphpGetGlobal() is logically just a copy of
|
|
the global variable, and it takes a call to hphpSetGlobal() to really update
|
|
the value of the global variable.
|