box/unbox hooks in C API

should help us pass C++ objects as args
This commit is contained in:
John Cupitt 2014-10-21 09:27:34 +01:00
parent f2898a8e3b
commit 904803510d
3 changed files with 35 additions and 3 deletions

View File

@ -70,6 +70,11 @@ void thread_shutdown()
vips_thread_shutdown(); vips_thread_shutdown();
} }
// see vips_image_new_from_file() // see vips_image_new_from_file()
VImage::VImage( const char *name, ... ) VImage::VImage( const char *name, ... )
__attribute__((sentinel)) throw( VError ) __attribute__((sentinel)) throw( VError )
@ -140,7 +145,7 @@ void VImage::write( const char *name, ... )
va_start( ap, name ); va_start( ap, name );
result = vips_call_split_option_string( operation_name, option_string, result = vips_call_split_option_string( operation_name, option_string,
ap, image, filename ); ap, this.im, filename );
va_end( ap ); va_end( ap );
if( result ) if( result )
@ -165,7 +170,7 @@ void *VImage::write( const char *suffix, size_t *size, ... )
va_start( ap, size ); va_start( ap, size );
result = vips_call_split_option_string( operation_name, option_string, result = vips_call_split_option_string( operation_name, option_string,
ap, in, &blob ); ap, this.im, &blob );
va_end( ap ); va_end( ap );
if( result ) if( result )

View File

@ -74,6 +74,20 @@ typedef struct _VipsOperation {
*/ */
int pixels; int pixels;
/* Get and set functions, used by eg. the C++ interface to box and
* unbox VImage.
*/
/* The value has been read from the VipsOperation and written to the arg
* pointer. @arg is eg. gboolean* for a bool value.
*/
void (*collect_get)( GParamSpec *pspec, void *arg );
/* The value has been read from argv into a GValue. Do any
* boxing/unboxing before the GValue is used to set the property.
*/
void (*collect_set)( GParamSpec *pspec, GValue *value );
} VipsOperation; } VipsOperation;
typedef struct _VipsOperationClass { typedef struct _VipsOperationClass {

View File

@ -603,6 +603,9 @@ vips_operation_set_valist_required( VipsOperation *operation, va_list ap )
} }
#endif /*VIPS_DEBUG */ #endif /*VIPS_DEBUG */
if( operation->collect_set )
operation->collect_set( pspec, &value );
g_object_set_property( G_OBJECT( operation ), g_object_set_property( G_OBJECT( operation ),
g_param_spec_get_name( pspec ), &value ); g_param_spec_get_name( pspec ), &value );
@ -645,7 +648,7 @@ vips_operation_get_valist_required( VipsOperation *operation, va_list ap )
/* It'd be nice to be able to test for arg being a /* It'd be nice to be able to test for arg being a
* valid gobject pointer, since passing in a valid * valid gobject pointer, since passing in a valid
* pointer, and having us destroy it, is a common * pointer (and having us destroy it) is a common
* error and a cause of hard-to-find leaks. * error and a cause of hard-to-find leaks.
* *
* Unfortunately, G_IS_OBJECT() can't be given an * Unfortunately, G_IS_OBJECT() can't be given an
@ -667,6 +670,11 @@ vips_operation_get_valist_required( VipsOperation *operation, va_list ap )
g_object_unref( object ); g_object_unref( object );
} }
/* Do any boxing/unboxing.
*/
if( operation->collect_get )
operation->collect_get( pspec, arg );
VIPS_ARGUMENT_COLLECT_END VIPS_ARGUMENT_COLLECT_END
} }
} VIPS_ARGUMENT_FOR_ALL_END } VIPS_ARGUMENT_FOR_ALL_END
@ -725,6 +733,11 @@ vips_operation_get_valist_optional( VipsOperation *operation, va_list ap )
object = *((GObject **) arg); object = *((GObject **) arg);
g_object_unref( object ); g_object_unref( object );
} }
/* Do any boxing/unboxing.
*/
if( operation->collect_get )
operation->collect_get( pspec, arg );
} }
VIPS_ARGUMENT_COLLECT_END VIPS_ARGUMENT_COLLECT_END