mirror of
https://github.com/awslabs/aws-crt-php.git
synced 2026-08-19 02:23:09 +00:00
Restored FFI to working order (#28)
* Restored FFI to working order * Disabled incompatible tests, fixed string conversion * Use extension_loaded instead of checking PHP version * Added better checks for FFI * Do not build FFI deps if no FFI is present
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
namespace AWS\CRT\Internal;
|
||||
|
||||
use Exception;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
* Forwards calls on to libaws-crt-ffi via FFI
|
||||
*/
|
||||
final class FFI {
|
||||
private static $ffi = null;
|
||||
private static $refcount = 0;
|
||||
|
||||
function __construct() {
|
||||
if (is_null(self::$ffi)) {
|
||||
try {
|
||||
$shlib_ext = 'so';
|
||||
$uname_s = php_uname('s');
|
||||
if ($uname_s == 'Darwin') {
|
||||
$shlib_ext = 'dylib';
|
||||
} else if ($uname_s == 'WINNT') {
|
||||
$shlib_ext = 'dll';
|
||||
}
|
||||
self::$ffi = \FFI::cdef(
|
||||
file_get_contents(__DIR__ . "/../../../api.h"),
|
||||
__DIR__ . "/../../../libaws-crt-ffi." . $shlib_ext);
|
||||
self::init();
|
||||
} catch (Exception $e) {
|
||||
throw new RuntimeException('Exception while initializing CRT via FFI', 0, $e);
|
||||
}
|
||||
}
|
||||
++self::$refcount;
|
||||
}
|
||||
|
||||
function __destruct() {
|
||||
if (--self::$refcount == 0) {
|
||||
self::clean_up();
|
||||
self::$ffi = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Forwards any call made on this object to the FFI function of the
|
||||
* same name with the supplied arguments. Argument type hinting and checking
|
||||
* occurs at the CRT wrapper.
|
||||
*/
|
||||
function __call(string $name, $args) {
|
||||
// Expand strings to (string, length)
|
||||
$ffi_args =[];
|
||||
foreach ($args as $arg) {
|
||||
if (is_string($arg)) {
|
||||
$len = strlen($arg);
|
||||
if ($len > 0) {
|
||||
$uint8_t = \FFI::type('uint8_t');
|
||||
$uint8_array = \FFI::arrayType($uint8_t, [$len]);
|
||||
$buf = \FFI::new($uint8_array);
|
||||
\FFI::memcpy($buf, $arg, $len);
|
||||
$ffi_args [] = $buf;
|
||||
$ffi_args [] = $len;
|
||||
} else {
|
||||
$ffi_args [] = null;
|
||||
$ffi_args [] = 0;
|
||||
}
|
||||
} else if (is_resource($arg)) {
|
||||
throw new RuntimeException("Resource types are not supported for FFI");
|
||||
} else {
|
||||
$ffi_args []= $arg;
|
||||
}
|
||||
}
|
||||
return call_user_func_array([self::$ffi, $name], $ffi_args);
|
||||
}
|
||||
|
||||
private static function init() {
|
||||
return self::$ffi->aws_crt_init();
|
||||
}
|
||||
|
||||
private static function clean_up() {
|
||||
return self::$ffi->aws_crt_clean_up();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user