Re: [Discussion] FFI in PHP
| From: | Michael Wallner | Date: | Wed, 08 Feb 2017 11:51:53 +0000 |
| Subject: | Re: [Discussion] FFI in PHP | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-98259@lists.php.net to get a copy of this message | ||
On 05/02/17 23:25, Alex Bowers wrote:
> And here is the previous messaging without borked formatting. Sorry folks.
>
>
> FFI RFC
> ======
..
> Example
> ===
>
> Take an example of a rust program that takes two numbers in and gives
> you the sum of them.
>
> ```rust
> #[no_mangle]
> pub extern fn add(a: i32, b: i32) -> i32 {
> a + b
> }
>
> ```
>
> with the Cargo.toml file containing:
>
> ```
> [package]
> name = "math"
> version = "0.1.0"
> authors = ["Alex Bowers <bowersbros@gmail.com>"]
>
> [dependencies]
>
> [lib]
> name = "math"
> crate-type = ["dylib"]
> ```
>
>
Attachment: [application/pgp-signature] OpenPGP digital signature signature.asc
cargo build --release will create
> .so, .dylib, or
> .dll files
> depending on your system.
>
> These should be usable within PHP using the exposed functions.
>
> ```php
> $math = ffi("/path/to/math.so");
> $result = $math->add(1, 5);
>
> echo $result; // 6
> ```
With ext/psi [1], that would work differently. You wouldn't define the
interface at runtime, like the above example, pecl/ffi [2] or MFFI [3].
First, you would create an interface description file (a PSI file [4]),
where you specify the native declaration and the library to load:
```
// https://github.com/m6w6/ext-psi#lib
lib "/path/to/math.so";
// https://github.com/m6w6/ext-psi#declarations
extern int32_t add(int32_t a, int32_t b);
```
The PHP interface to this function would usually be defined in the same
file possibly looking along the following lines:
```
// https://github.com/m6w6/ext-psi#implementations
function math\add(int $a, int $b) : int {
let a = intval($a);
let b = intval($b);
return to_int(add);
}
```
Those PSI files would be loaded from a directory configured in php.ini
(psi.directory) and loaded at startup, i.e. the interfaces would be
available to user land for the lifetime of the process, not the request.
Have a look at the complete libidn example [5] of the README or the
sqlite test [6] utilizing a user land callback.
I've been working on ext/psi for the good parts of more than a year now,
and I would be more than happy about insights, suggestions or
collaboration with other interested parties.
The (currently) two major to-dos are decent CPP support in the parser,
so one could basically just parse C headers, and levelling out support
for input/output marshalling, which currently differ in sophistication,
AFAIR, while quite a lot is already possible. Other random bits can be
found in the TODO [7].
It has been successfully built and run on Linux and OSX but YMMV; also,
grab a coffee when building the first time, because configure performs
a ton of checks for POSIX builtins (still like, 10% only yet), so don't
forget the -C/--cache-file switch.
[1] https://github.com/m6w6/ext-psi
[2] https://pecl.php.net/ffi
[3] https://github.com/mgdm/MFFI
[4] https://github.com/m6w6/ext-psi#psi-files
[5] https://github.com/m6w6/ext-psi#complete-example
[6] https://github.com/m6w6/ext-psi/tree/master/tests/sqlite
[7] https://github.com/m6w6/ext-psi/blob/master/TODO
--
Regards,
Mike
Attachment: [application/pgp-signature] OpenPGP digital signature signature.asc