diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2023-03-20 12:57:16 +0100 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2023-03-20 12:57:16 +0100 |
commit | 75a7a04edffe5caf501d18428e4b6a5ceff90a91 (patch) | |
tree | be5d5504814c9092356948ff270f2df5e1a9ad71 | |
parent | 70a162188ffa0301589fdaf0e0d8d3058829ce06 (diff) |
Use callback functins with C linkage
* cairomm/script.cc:
* cairomm/surface.cc: Use local 'extern "C"' callback functions.
Code that mixes up C linkage and C++ linkage has undefined behavior.
Most compilers make no difference between C and C++ linkage, so it
has not been an issue so far. But see issue glibmm#1.
-rw-r--r-- | cairomm/script.cc | 14 | ||||
-rw-r--r-- | cairomm/surface.cc | 28 |
2 files changed, 33 insertions, 9 deletions
diff --git a/cairomm/script.cc b/cairomm/script.cc index 1caaf31..2f705c9 100644 --- a/cairomm/script.cc +++ b/cairomm/script.cc @@ -80,6 +80,17 @@ cairo_status_t device_write_func_wrapper(void* closure, const unsigned char* dat return static_cast<cairo_status_t>((*write_func)(data, length)); } +//TODO: When we can break ABI, move the code from device_write_func_wrapper() +// to c_device_write_func_wrapper() and remove device_write_func_wrapper(). +extern "C" +{ +static cairo_status_t c_device_write_func_wrapper( + void* closure, const unsigned char* data, unsigned int length) +{ + return device_write_func_wrapper(closure, data, length); +} +} // extern "C" + static void set_write_slot(cairo_device_t* surface, Surface::SlotWriteFunc* slot) { // the slot will automatically be freed by device_free_slot() when the @@ -91,8 +102,7 @@ static void set_write_slot(cairo_device_t* surface, RefPtr<Script> Script::create_for_stream(const Surface::SlotWriteFunc& write_func) { auto slot_copy = new Surface::SlotWriteFunc(write_func); - auto cobject = cairo_script_create_for_stream(device_write_func_wrapper, - slot_copy); + auto cobject = cairo_script_create_for_stream(c_device_write_func_wrapper, slot_copy); check_status_and_throw_exception(cairo_device_status(cobject)); set_write_slot(cobject, slot_copy); return make_refptr_for_instance<Script>(new Script(cobject, true /* has reference */)); diff --git a/cairomm/surface.cc b/cairomm/surface.cc index 9982625..275c2ae 100644 --- a/cairomm/surface.cc +++ b/cairomm/surface.cc @@ -69,6 +69,21 @@ cairo_status_t write_func_wrapper(void* closure, const unsigned char* data, unsi return static_cast<cairo_status_t>((*write_func)(data, length)); } +//TODO: When we can break ABI, move the code from [read,write]_func_wrapper() +// to c_[read,write]_func_wrapper() and remove [read,write]_func_wrapper(). +extern "C" +{ +static cairo_status_t c_read_func_wrapper(void* closure, unsigned char* data, unsigned int length) +{ + return read_func_wrapper(closure, data, length); +} + +static cairo_status_t c_write_func_wrapper(void* closure, const unsigned char* data, unsigned int length) +{ + return write_func_wrapper(closure, data, length); +} +} // extern "C" + Surface::Surface(cairo_surface_t* cobject, bool has_reference) : m_cobject(nullptr) { @@ -245,9 +260,8 @@ void Surface::write_to_png_stream(const SlotWriteFunc& write_func) delete old_slot; auto slot_copy = new SlotWriteFunc(write_func); set_write_slot(cobj(), slot_copy); - auto status = cairo_surface_write_to_png_stream(cobj(), - &write_func_wrapper, - slot_copy /*closure*/); + auto status = cairo_surface_write_to_png_stream( + cobj(), &c_write_func_wrapper, slot_copy /*closure*/); check_status_and_throw_exception(status); } #endif @@ -333,7 +347,7 @@ RefPtr<ImageSurface> ImageSurface::create_from_png_stream(const SlotReadFunc& re { auto slot_copy = new SlotReadFunc(read_func); auto cobject = - cairo_image_surface_create_from_png_stream(&read_func_wrapper, slot_copy); + cairo_image_surface_create_from_png_stream(&c_read_func_wrapper, slot_copy); check_status_and_throw_exception(cairo_surface_status(cobject)); set_read_slot(cobject, slot_copy); return make_refptr_for_instance<ImageSurface>(new ImageSurface(cobject, true /* has reference */)); @@ -451,7 +465,7 @@ RefPtr<PdfSurface> PdfSurface::create_for_stream(const SlotWriteFunc& write_func { auto slot_copy = new SlotWriteFunc(write_func); auto cobject = - cairo_pdf_surface_create_for_stream(write_func_wrapper, slot_copy, + cairo_pdf_surface_create_for_stream(c_write_func_wrapper, slot_copy, width_in_points, height_in_points); check_status_and_throw_exception(cairo_surface_status(cobject)); set_write_slot(cobject, slot_copy); @@ -519,7 +533,7 @@ RefPtr<PsSurface> PsSurface::create_for_stream(const SlotWriteFunc& write_func, { auto slot_copy = new SlotWriteFunc(write_func); auto cobject = - cairo_ps_surface_create_for_stream(write_func_wrapper, slot_copy, + cairo_ps_surface_create_for_stream(c_write_func_wrapper, slot_copy, width_in_points, height_in_points); check_status_and_throw_exception(cairo_surface_status(cobject)); set_write_slot(cobject, slot_copy); @@ -621,7 +635,7 @@ RefPtr<SvgSurface> SvgSurface::create_for_stream(const SlotWriteFunc& write_func { auto slot_copy = new SlotWriteFunc(write_func); auto cobject = - cairo_svg_surface_create_for_stream(write_func_wrapper, slot_copy, + cairo_svg_surface_create_for_stream(c_write_func_wrapper, slot_copy, width_in_points, height_in_points); check_status_and_throw_exception(cairo_surface_status(cobject)); set_write_slot(cobject, slot_copy); |