Skip to content

php-ffi on windows fails to link to g_malloc and g_free #144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
jcupitt opened this issue May 23, 2022 · 7 comments · Fixed by #146
Closed

php-ffi on windows fails to link to g_malloc and g_free #144

jcupitt opened this issue May 23, 2022 · 7 comments · Fixed by #146
Labels

Comments

@jcupitt
Copy link
Member

jcupitt commented May 23, 2022

Config.php tries to link to g_malloc and g_free (glib functions) in the libvips shared library. This works on linux, since it can resolve indirect dependencies, but maybe windows needs the exact shared library that contains the named function.

Experiment with directly linking to glib and gobject. ruby-vips does this and seems to work on windows.

See: https://stackoverflow.com/questions/72330264/libvips-ffi-use-on-windows-php-cannot-find-glib-functions

@jcupitt jcupitt added the bug label May 23, 2022
@syslogic
Copy link

syslogic commented May 23, 2022

This would provide it: https://github.com/GNOME/glib/blob/main/glib/gmem.c ...which reads:

Since GLib 2.46 g_malloc() is hardcoded to always use the system malloc implementation.

Also concerning g_free() ...does one even needs a library for that?

@jcupitt
Copy link
Member Author

jcupitt commented May 23, 2022

It's a historical accident -- glib used (10+ years ago) to have its own malloc implementation, and therefore needed its own free. These days they just use the platform malloc (thank goodness). You still need to use the g_*() versions though.

@syslogic
Copy link

syslogic commented May 25, 2022

I'm not exactly sure if the G stands for GNU or GNOME,
... but the target system might be missing the library:
http://www.gnu.org/software/libc/libc.html

@codercms
Copy link

codercms commented Jun 19, 2022

Hey guys! Could you give me advice how to statically link libvips with glib?
I have the same issue with g_* functions.

@kleisauke
Copy link
Member

This commit is also relevant here: kleisauke/net-vips@e04c6b0. I think there are at least 3 ways to solve this (ordered from easy to difficult):

  1. Split the GLib and GObject symbols into a separate string and use libglib-2.0-0.dll and libgobject-2.0-0.dll respectively as the name of the shared library on Windows. This is not necessary on Linux and macOS.
  2. Build and distribute libvips on Windows as a single shared library with the GLib and GObject symbols exported. See e.g. the single-shared branch.
  3. Do the same as above, but create a compatibility layer in libvips that wraps all GLib and GObject symbols rather than exporting them (e.g. g_object_unref becomes vips_object_unref, see: Add back g_object_unref wrapper (like im_close) libvips#2788). This would also require an update to the binding to use this new API.

Note that point 2 would break compatibility with the shared Windows builds, plus all libvips bindings based on FFI needs to be updated to avoid libglib-2.0-0.dll and libgobject-2.0-0.dll. Point 3 has the same disadvantages as point 2, plus would break backwards compatibility with older libvips versions (as it uses those new symbols).

Since this is only a issue on Windows, I think point 1 is the most straightforward. I might look into making a PR somewhere tomorrow.

@kleisauke
Copy link
Member

I just opened PR #146 for this. Any testing would be welcome (especially on Windows 32-bit).

@codercms
Copy link

@kleisauke just tested your PR on x64 Windows (currently I don't have win x86). It works fine!

Code:
<?php

require_once __DIR__ . '/vendor/autoload.php';

use Jcupitt\Vips;

$paths = [
    'C:\Users\user\Pictures\photo_2021-01-15_17-04-50.jpg',
    'C:\Users\user\Pictures\Untitled2.png',
    'C:\Users\user\Pictures\fox.profile0.8bpc.yuv420.avif',
];

echo "File open test" . PHP_EOL;

foreach ($paths as $path) {
    var_dump($path);

    $img = file_get_contents($path);
    $res = Vips\Image::newFromBuffer($img);

    var_dump("{$res->width}x{$res->height}, {$res->format}, {$res->coding}, {$res->interpretation}, {$res->bands}");
}

echo PHP_EOL;
echo "Thumbnail write test" . PHP_EOL;

foreach ($paths as $path) {
    var_dump($path);

    $filename = pathinfo($path, PATHINFO_FILENAME);

    $res = Vips\Image::thumbnail_buffer(file_get_contents($path), 600, [
        'size' => 'down',
        'export_profile' => 'srgb',
    ]);

    var_dump("{$res->width}x{$res->height}, {$res->format}, {$res->coding}, {$res->interpretation}, {$res->bands}");

    $res->writeToFile("thumb_{$filename}.jpg", [
        'optimize_coding' => true,
        'strip' => true,
        'interlace' => true,
        'background' => 255,
        'Q' => 90,
    ]);

    $res = Vips\Image::thumbnail($path, 600, [
        'size' => 'down',
        'export_profile' => 'srgb',
    ]);

    $buf = $res->writeToBuffer(".jpg", [
        'optimize_coding' => true,
        'strip' => true,
        'interlace' => true,
        'background' => 255,
        'Q' => 90,
    ]);

    file_put_contents("thumb2_{$filename}.jpg", $buf);
}
Output:
PS C:\Users\user\Documents\PhpProjects\php-img\php-vips-fork> php test.php
File open test
string(53) "C:\Users\user\Pictures\photo_2021-01-15_17-04-50.jpg"
string(30) "960x1280, uchar, none, srgb, 3"
string(37) "C:\Users\user\Pictures\Untitled2.png"
string(31) "1025x1137, uchar, none, srgb, 4"
string(53) "C:\Users\user\Pictures\fox.profile0.8bpc.yuv420.avif"
string(30) "1204x800, uchar, none, srgb, 3"

Thumbnail write test
string(53) "C:\Users\user\Pictures\photo_2021-01-15_17-04-50.jpg"
string(29) "450x600, uchar, none, srgb, 3"
string(37) "C:\Users\user\Pictures\Untitled2.png"
string(29) "541x600, uchar, none, srgb, 4"
string(53) "C:\Users\user\Pictures\fox.profile0.8bpc.yuv420.avif"
string(29) "600x399, uchar, none, srgb, 3"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants