summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjellahlstedt@gmail.com>2023-03-20 12:57:16 +0100
committerKjell Ahlstedt <kjellahlstedt@gmail.com>2023-03-20 12:57:16 +0100
commit75a7a04edffe5caf501d18428e4b6a5ceff90a91 (patch)
treebe5d5504814c9092356948ff270f2df5e1a9ad71
parent70a162188ffa0301589fdaf0e0d8d3058829ce06 (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.cc14
-rw-r--r--cairomm/surface.cc28
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);