Skip to content
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

Fix -Wincompatible-function-pointer-types warning on Clang #461

Merged
merged 1 commit into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 8 additions & 27 deletions pyvips/gvalue.py
Original file line number Diff line number Diff line change
Expand Up @@ -226,36 +226,17 @@ def set(self, value):
memory = glib_lib.g_malloc(len(value))
ffi.memmove(memory, value, len(value))

# this is horrible!
#
# * in API mode, we must have 8.6+ and use set_blob_free to
# attach the metadata to avoid leaks
# * pre-8.6, we just pass a NULL free pointer and live with the
# leak
#
# this is because in API mode you can't pass a builtin (what
# vips_lib.g_free() becomes) as a parameter to ffi.callback(), and
# vips_value_set_blob() needs a callback for arg 2
#
# additionally, you can't make a py def which calls g_free() and
# then use the py def in the callback, since libvips will trigger
# these functions during cleanup, and py will have shut down by
# then and you'll get a segv

if at_least_libvips(8, 6):
# In API mode, we use set_blob_free in a backwards compatible way.
# For pre-8.6 libvipses, in ABI mode, we declare the type of the
# free func in set_blob incorrectly so that we can pass g_free
# at runtime without triggering an exception.
if pyvips.API_mode or at_least_libvips(8, 6):
vips_lib.vips_value_set_blob_free(self.gvalue,
memory, len(value))
else:
# we declare the type of the free func in set_blob incorrectly
# so that we can pass g_free at runtime without triggering an
# exception
if pyvips.API_mode:
vips_lib.vips_value_set_blob(self.gvalue,
ffi.NULL, memory, len(value))
else:
vips_lib.vips_value_set_blob(self.gvalue,
glib_lib.g_free,
memory, len(value))
vips_lib.vips_value_set_blob(self.gvalue,
glib_lib.g_free,
memory, len(value))
else:
raise Error('unsupported gtype for set {0}, fundamental {1}'.
format(type_name(gtype), type_name(fundamental)))
Expand Down
34 changes: 26 additions & 8 deletions pyvips/pyvips_build.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@
if pkgconfig.installed('vips', '< 8.2'):
raise Exception('pkg-config "vips" is too old -- need libvips 8.2 or later')

ffibuilder = FFI()

ffibuilder.set_source("_libvips",
r"""
#include <vips/vips.h>
""",
**pkgconfig.parse('vips'))

# pkgconfig 1.5+ has modversion ... otherwise, use a small shim
try:
from pkgconfig import modversion
Expand All @@ -31,6 +23,32 @@ def modversion(package):

major, minor, micro = [int(s) for s in modversion('vips').split('.')]

ffibuilder = FFI()

# vips_value_set_blob_free and vips_area_free_cb compat for libvips < 8.6
compat = '''
int
vips_area_free_cb(void *mem, VipsArea *area)
{
g_free(mem);

return 0;
}

void
vips_value_set_blob_free(GValue* value, void* data, size_t length)
{
vips_value_set_blob(value, (VipsCallbackFn) vips_area_free_cb,
data, length);
}
''' if major == 8 and minor < 6 else ''

ffibuilder.set_source("_libvips",
r"""
#include <vips/vips.h>
""" + compat,
**pkgconfig.parse('vips'))

features = {
'major': major,
'minor': minor,
Expand Down
12 changes: 9 additions & 3 deletions pyvips/vdecls.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,6 @@ def cdefs(features):
void vips_value_set_array_int (GValue* value,
const int* array, int n );
void vips_value_set_array_image (GValue *value, int n);
typedef void (*FreeFn)(void* a);
void vips_value_set_blob (GValue* value,
FreeFn free_fn, void* data, size_t length);

int g_value_get_boolean (const GValue* value);
int g_value_get_int (GValue* value);
Expand Down Expand Up @@ -405,6 +402,15 @@ def cdefs(features):
int vips_cache_get_max_files();
'''

# we must only define this in ABI mode ... in API mode we use
# vips_value_set_blob_free in a backwards compatible way
if not features['api']:
code += '''
typedef void (*FreeFn)(void* a);
void vips_value_set_blob (GValue* value,
FreeFn free_fn, void* data, size_t length);
'''

if _at_least(features, 8, 5):
code += '''
char** vips_image_get_fields (VipsImage* image);
Expand Down
Loading