diff options
author | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2023-03-31 15:24:13 +0200 |
---|---|---|
committer | Kjell Ahlstedt <kjellahlstedt@gmail.com> | 2023-03-31 15:24:13 +0200 |
commit | 98f3b67b5c1bd71d0e7b41193fb4683fc957e321 (patch) | |
tree | 1fa8a4cf1bf9a93a79bfe08be83426bb15da01e9 /glib/src | |
parent | b7ad9b86d70003c065606c563578cc66dcd2ce0a (diff) | |
download | glibmm-98f3b67b5c1bd71d0e7b41193fb4683fc957e321.tar.gz |
Glib: Use callback functions with C linkageglibmm-2-76
* gio/src/cancellable.ccg: Add TODO comment.
* glib/glibmm/class.cc: Call custom_class_base_finalize_function() and
custom_class_init_function() via local functions with C linkage.
* glib/glibmm/extraclassinit.h: Point out in the class documentation that
the class init and instance init functions shall have C linkage.
* glib/glibmm/main.[cc|h]: Call prepare_vfunc(), check_vfunc() and
dispatch_vfunc() via local functions with C linkage.
* glib/glibmm/objectbase.cc: Call destroy_notify_callback()
via a local function with C linkage.
* glib/glibmm/propertyproxy_base.cc: Call PropertyProxyConnectionNode::
callback() and destroy_notify_handler() via local functions with C linkage.
* glib/glibmm/signalproxy.cc: Call SignalProxyNormal::slot0_void_callback()
and SignalProxyConnectionNode::destroy_notify_handler() via local functions
with C linkage.
* glib/src/binding.ccg: Add extern "C".
* glib/src/bytearray.ccg: Add a TODO comment.
* glib/src/markup.ccg: Call functions in the vfunc table via local
functions with C linkage.
* glib/src/optioncontext.ccg: Add extern "C".
* glib/src/optiongroup.ccg: Call post_parse_callback() and
option_arg_callback() via local functions with C linkage.
Part of issue #1
Diffstat (limited to 'glib/src')
-rw-r--r-- | glib/src/binding.ccg | 10 | ||||
-rw-r--r-- | glib/src/bytearray.ccg | 12 | ||||
-rw-r--r-- | glib/src/markup.ccg | 72 | ||||
-rw-r--r-- | glib/src/optioncontext.ccg | 4 | ||||
-rw-r--r-- | glib/src/optiongroup.ccg | 37 |
5 files changed, 118 insertions, 17 deletions
diff --git a/glib/src/binding.ccg b/glib/src/binding.ccg index ff753380..f759ab3c 100644 --- a/glib/src/binding.ccg +++ b/glib/src/binding.ccg @@ -49,7 +49,9 @@ Binding_transform_callback_common( return result; } -gboolean +extern "C" +{ +static gboolean Binding_transform_to_callback( GBinding*, const GValue* from_value, GValue* to_value, gpointer user_data) { @@ -59,7 +61,7 @@ Binding_transform_to_callback( return Binding_transform_callback_common(from_value, to_value, the_slot); } -gboolean +static gboolean Binding_transform_from_callback( GBinding*, const GValue* from_value, GValue* to_value, gpointer user_data) { @@ -69,12 +71,12 @@ Binding_transform_from_callback( return Binding_transform_callback_common(from_value, to_value, the_slot); } -void +static void Binding_transform_callback_destroy(gpointer user_data) { delete static_cast<BindingTransformSlots*>(user_data); } - +} // extern "C" } // anonymous namespace namespace Glib diff --git a/glib/src/bytearray.ccg b/glib/src/bytearray.ccg index c04fa004..393dad13 100644 --- a/glib/src/bytearray.ccg +++ b/glib/src/bytearray.ccg @@ -16,9 +16,11 @@ namespace { - -extern "C" { - +extern "C" +{ +// Non-static functions with C linkage get external linkage, even if they are +// defined in an anonymous namespace. +//TODO: Declare 'static' when we can break ABI. int ByteArray_Compare_Data_Func(gconstpointer a, gconstpointer b, gpointer user_data) { @@ -26,8 +28,8 @@ ByteArray_Compare_Data_Func(gconstpointer a, gconstpointer b, gpointer user_data return (*slot)(static_cast<const guint8*>(a), static_cast<const guint8*>(b)); } -} -} +} // extern "C" +} // anonymous namespace namespace Glib { diff --git a/glib/src/markup.ccg b/glib/src/markup.ccg index 408b1688..b41ba2e9 100644 --- a/glib/src/markup.ccg +++ b/glib/src/markup.ccg @@ -45,6 +45,7 @@ AttributeKeyLess::operator()(const Glib::ustring& lhs, const Glib::ustring& rhs) class ParserCallbacks { public: + //TODO: When we can break ABI, remove vfunc_table. static const GMarkupParser vfunc_table; static void start_element(GMarkupParseContext* context, const char* element_name, @@ -183,6 +184,72 @@ ParserCallbacks::error(GMarkupParseContext* context, GError* error, void* user_d } } +} // namespace Markup +} // namespace Glib + +/**** anonymous namespace *************************************************/ + +namespace +{ +using ParseContext_destroy_notify_callback_functype = void (*) (void* data); +ParseContext_destroy_notify_callback_functype ParseContext_destroy_notify_callback_funcptr; + +extern "C" +{ +static void ParseContext_destroy_notify_c_callback(void* data) +{ + ParseContext_destroy_notify_callback_funcptr(data); +} + +static void ParserCallbacks_start_element(GMarkupParseContext* context, + const char* element_name, const char** attribute_names, + const char** attribute_values, void* user_data, GError** error) +{ + Glib::Markup::ParserCallbacks::start_element(context, element_name, + attribute_names, attribute_values, user_data, error); +} + +static void ParserCallbacks_end_element(GMarkupParseContext* context, + const char* element_name, void* user_data, GError** error) +{ + Glib::Markup::ParserCallbacks::end_element(context, element_name, user_data, error); +} + +static void ParserCallbacks_text(GMarkupParseContext* context, const char* text, + gsize text_len, void* user_data, GError** error) +{ + Glib::Markup::ParserCallbacks::text(context, text, text_len, user_data, error); +} + +static void ParserCallbacks_passthrough(GMarkupParseContext* context, + const char* passthrough_text, gsize text_len, void* user_data, GError** error) +{ + Glib::Markup::ParserCallbacks::passthrough(context, passthrough_text, + text_len, user_data, error); +} + +static void ParserCallbacks_error(GMarkupParseContext* context, GError* error, + void* user_data) +{ + Glib::Markup::ParserCallbacks::error(context, error, user_data); +} + +static const GMarkupParser ParserCallbacks_vfunc_table = { + &ParserCallbacks_start_element, + &ParserCallbacks_end_element, + &ParserCallbacks_text, + &ParserCallbacks_passthrough, + &ParserCallbacks_error +}; + +} // extern "C" +} // anonymous namespace + +namespace Glib +{ +namespace Markup +{ + /**** Glib::Markup::Parser *************************************************/ Parser::Parser() @@ -233,9 +300,10 @@ Parser::on_error(ParseContext&, const MarkupError&) ParseContext::ParseContext(Parser& parser, ParseFlags flags) : parser_(&parser), - gobject_(g_markup_parse_context_new(&ParserCallbacks::vfunc_table, (GMarkupParseFlags)flags, this, - &ParseContext::destroy_notify_callback)) + gobject_(g_markup_parse_context_new(&ParserCallbacks_vfunc_table, (GMarkupParseFlags)flags, this, + &ParseContext_destroy_notify_c_callback)) { + ParseContext_destroy_notify_callback_funcptr = &destroy_notify_callback; } ParseContext::ParseContext(ParseContext&& other) noexcept : sigc::trackable(std::move(other)), diff --git a/glib/src/optioncontext.ccg b/glib/src/optioncontext.ccg index b63434e8..ad86903e 100644 --- a/glib/src/optioncontext.ccg +++ b/glib/src/optioncontext.ccg @@ -23,6 +23,8 @@ namespace Glib namespace OptionContextPrivate { +extern "C" +{ static const gchar* SignalProxy_translate_gtk_callback(const gchar* str, gpointer data) { @@ -46,7 +48,7 @@ SignalProxy_translate_gtk_callback_destroy(gpointer data) { delete static_cast<Glib::OptionContext::SlotTranslate*>(data); } - +} // extern "C" } // namespace OptionContextPrivate OptionContext::OptionContext(const Glib::ustring& parameter_string) diff --git a/glib/src/optiongroup.ccg b/glib/src/optiongroup.ccg index ee9b7bfe..543a5ab0 100644 --- a/glib/src/optiongroup.ccg +++ b/glib/src/optiongroup.ccg @@ -64,7 +64,29 @@ private: OptionArgCallback& operator=(const OptionArgCallback&); }; -extern "C" { +using OptionGroupPostParseFuncType = gboolean (*)(GOptionContext* context, + GOptionGroup* group, gpointer data, GError** error); +using OptionGroupOptionArgFuncType = gboolean (*)(const gchar* option_name, + const gchar* value, gpointer data, GError** error); +OptionGroupPostParseFuncType OptionGroup_post_parse_callback_funcptr; +OptionGroupOptionArgFuncType OptionGroup_option_arg_callback_funcptr; + +extern "C" +{ +// From functions with C linkage, to protected static member functions with C++ linkage +static gboolean +OptionGroup_post_parse_callback(GOptionContext* context, GOptionGroup* group, + gpointer data, GError** error) +{ + return OptionGroup_post_parse_callback_funcptr(context, group, data, error); +} + +static gboolean +OptionGroup_option_arg_callback(const gchar* option_name, const gchar* value, + gpointer data, GError** error) +{ + return OptionGroup_option_arg_callback_funcptr(option_name, value, data, error); +} static gboolean g_callback_pre_parse( @@ -119,6 +141,9 @@ g_callback_error( } } +// Non-static functions with C linkage get external linkage, even if they are +// defined in an anonymous namespace. +//TODO: Declare 'static' when we can break ABI. const gchar* OptionGroup_Translate_glibmm_callback(const gchar* string, gpointer data) { @@ -284,7 +309,8 @@ OptionGroup::OptionGroup(const Glib::ustring& name, const Glib::ustring& descrip // original OptionGroup instance. // Connect callbacks, so that derived classes can override the virtual methods: - g_option_group_set_parse_hooks(gobj(), &g_callback_pre_parse, &post_parse_callback); + OptionGroup_post_parse_callback_funcptr = &post_parse_callback; + g_option_group_set_parse_hooks(gobj(), &g_callback_pre_parse, &OptionGroup_post_parse_callback); g_option_group_set_error_hook(gobj(), &g_callback_error); } @@ -553,19 +579,20 @@ OptionGroup::CppOptionEntry::allocate_c_arg() { // The C arg pointer is a function pointer, cast to void*. // - // carg_ = reinterpret_cast<void*>(&OptionGroup::option_arg_callback); + // carg_ = reinterpret_cast<void*>(&OptionGroup_option_arg_callback); // or // union { // void* dp; // GOptionArgFunc fp; // } u; - // u.fp = &OptionGroup::option_arg_callback; + // u.fp = &OptionGroup_option_arg_callback; // carg_ = u.dp; // ? See // https://bugzilla.gnome.org/show_bug.cgi?id=589197 // https://github.com/libsigcplusplus/libsigcplusplus/issues/1 // https://github.com/libsigcplusplus/libsigcplusplus/issues/8 - carg_ = reinterpret_cast<void*>(&OptionGroup::option_arg_callback); + carg_ = reinterpret_cast<void*>(&OptionGroup_option_arg_callback); + OptionGroup_option_arg_callback_funcptr = &OptionGroup::option_arg_callback; break; } |