Skip to content

Commit 57b593a

Browse files
authored
FFI class improvements (fixes #221) (#230)
* FFI class improvements * Update missed heredoc; use generic lib location
1 parent 7cf9d49 commit 57b593a

File tree

1 file changed

+32
-27
lines changed

1 file changed

+32
-27
lines changed

Diff for: src/FFI.php

+32-27
Original file line numberDiff line numberDiff line change
@@ -180,10 +180,10 @@ public static function shutDown(): void
180180

181181
public static function newGClosure(): \FFI\CData
182182
{
183-
// GClosure measures 32-bit with the first few fields until marshal
184-
// Marshal is a function pointer, thus platform-dependant.
185-
// Data is a pointer, thus platform-dependant.
186-
// Notifiers is an array-pointer, thus platform-dependant.
183+
// GClosure measures 32-bit with the first few fields until marshal.
184+
// - Marshal is a function pointer, thus platform-dependant.
185+
// - Data is a pointer, thus platform-dependant.
186+
// - Notifiers is an array-pointer, thus platform-dependant.
187187
// All in all it's basically 4 (bytes) + 3 * POINTER_SIZE
188188
// However, gobject wants 8 (bytes) + 3 * POINTER_SIZE.
189189
// I'm not sure where that extra byte comes from. Padding on 64-bit machines?
@@ -210,7 +210,7 @@ private static function libraryLoad(
210210
array $libraryPaths,
211211
string $libraryName,
212212
string $interface
213-
): \FFI {
213+
): ?\FFI {
214214
Utils::debugLog("trying to open", ["libraryName" => $libraryName]);
215215
foreach ($libraryPaths as $path) {
216216
Utils::debugLog("trying path", ["path" => $path]);
@@ -225,6 +225,7 @@ private static function libraryLoad(
225225
]);
226226
}
227227
}
228+
return null;
228229
}
229230

230231
private static function init(): void
@@ -234,7 +235,7 @@ private static function init(): void
234235
return;
235236
}
236237

237-
// the two usual install problems
238+
// the two usual installation problems
238239
if (!extension_loaded('ffi')) {
239240
throw new Exception('FFI extension not loaded');
240241
}
@@ -267,16 +268,18 @@ private static function init(): void
267268
$libraryPaths[] = $vipshome . "/lib/";
268269
}
269270

270-
if (PHP_OS_FAMILY === "OSX" ||
271-
PHP_OS_FAMILY === "Darwin") {
272-
$libraryPaths[] = "/opt/homebrew/lib/"; // Homebrew on Apple Silicon
271+
if (PHP_OS_FAMILY === "OSX" || PHP_OS_FAMILY === "Darwin") {
272+
// Homebrew on Apple Silicon
273+
$libraryPaths[] = "/opt/homebrew/lib/";
274+
// See https://github.com/Homebrew/brew/issues/13481#issuecomment-1207203483
275+
$libraryPaths[] = "/usr/local/lib/";
273276
}
274277

275-
$vips = self::libraryLoad($libraryPaths, $vips_libname, <<<EOS
278+
$vips = self::libraryLoad($libraryPaths, $vips_libname, <<<'CPP'
276279
int vips_init (const char *argv0);
277280
const char *vips_error_buffer (void);
278281
int vips_version(int flag);
279-
EOS);
282+
CPP);
280283

281284
if ($vips === null) {
282285
// drop the "" (system path) member
@@ -313,19 +316,21 @@ private static function init(): void
313316
"8.7 or later required");
314317
}
315318

316-
// GType is the size of a pointer
317-
$gtype = $is_64bits ? "guint64" : "guint32";
318-
319319
// Typedefs shared across the libvips, GLib and GObject declarations
320-
$typedefs = <<<EOS
320+
$typedefs = <<<'CPP'
321321
// we need the glib names for these types
322322
typedef uint32_t guint32;
323323
typedef int32_t gint32;
324324
typedef uint64_t guint64;
325325
typedef int64_t gint64;
326326
typedef void* gpointer;
327327

328-
typedef $gtype GType;
328+
CPP;
329+
330+
// GType is the size of a pointer
331+
$typedefs .= 'typedef ' . ($is_64bits ? 'guint64' : 'guint32') . ' GType;';
332+
333+
$typedefs .= <<<'CPP'
329334
330335
typedef struct _GData GData;
331336
@@ -340,17 +345,17 @@ private static function init(): void
340345
unsigned int ref_count;
341346
GData *qdata;
342347
} GObject;
343-
EOS;
348+
CPP;
344349

345350
// GLib declarations
346-
$glib_decls = $typedefs . <<<EOS
351+
$glib_decls = $typedefs . <<<'CPP'
347352
void* g_malloc (size_t size);
348353
void g_free (void* data);
349354
void g_strfreev (char** str_array);
350-
EOS;
355+
CPP;
351356

352357
// GObject declarations
353-
$gobject_decls = $typedefs . <<<EOS
358+
$gobject_decls = $typedefs . <<<'CPP'
354359
typedef struct _GValue {
355360
GType g_type;
356361
guint64 data[2];
@@ -467,10 +472,10 @@ private static function init(): void
467472
void g_closure_set_marshal(GClosure* closure, marshaler marshal);
468473
long g_signal_connect_closure(GObject* object, const char* detailed_signal, GClosure *closure, bool after);
469474
GClosure* g_closure_new_simple (int sizeof_closure, void* data);
470-
EOS;
475+
CPP;
471476

472477
# the whole libvips API, mostly adapted from pyvips
473-
$vips_decls = $typedefs . <<<EOS
478+
$vips_decls = $typedefs . <<<'CPP'
474479
typedef struct _VipsImage VipsImage;
475480
typedef struct _VipsProgress VipsProgress;
476481
@@ -696,10 +701,10 @@ private static function init(): void
696701
697702
int vips_object_get_args (VipsObject* object,
698703
const char*** names, int** flags, int* n_args);
699-
EOS;
704+
CPP;
700705

701706
if (self::atLeast(8, 8)) {
702-
$vips_decls = $vips_decls . <<<EOS
707+
$vips_decls = $vips_decls . <<<'CPP'
703708
char** vips_foreign_get_suffixes (void);
704709
705710
void* vips_region_fetch (VipsRegion*, int, int, int, int,
@@ -708,11 +713,11 @@ private static function init(): void
708713
int vips_region_height (VipsRegion*);
709714
int vips_image_get_page_height (VipsImage*);
710715
int vips_image_get_n_pages (VipsImage*);
711-
EOS;
716+
CPP;
712717
}
713718

714719
if (self::atLeast(8, 8)) {
715-
$vips_decls = $vips_decls . <<<EOS
720+
$vips_decls = $vips_decls . <<<'CPP'
716721
typedef struct _VipsConnection {
717722
VipsObject parent_object;
718723
@@ -761,7 +766,7 @@ private static function init(): void
761766
762767
const char* vips_foreign_find_load_source (VipsSource *source);
763768
const char* vips_foreign_find_save_target (const char* suffix);
764-
EOS;
769+
CPP;
765770
}
766771

767772
Utils::debugLog("init", ["binding ..."]);

0 commit comments

Comments
 (0)