弱函数与单文件头文件库

huangapple go评论64阅读模式
英文:

Weak functions with single-file header libraries

问题

我维护rawdraw,而rawdraw使用全局符号来回调,用于创建、输入和闭包。我想要自动使用一个符号的副本,比如,如果用户没有定义一个符号,或者如果用户定义了一个符号,我想要使用它。

这对大多数平台来说不是问题,但对于Android来说非常烦人,因为在应用程序在设备上运行之前,你无法识别链接器问题。

问题出在头文件中。所以我想要的是一种方式,从同一个C文件中允许函数调用被覆盖,但不要求它。

我尝试过weakweak,aliasof(...)属性,似乎都不允许在同一个C文件中覆盖符号。

例如,在这种情况下,用户想要允许检测窗口终止,但这个库的许多用户不关心。

cnfg.h

void HandleWindowTermination();

...

	case APP_CMD_TERM_WINDOW:
              ...
		HandleWindowTermination();
		break;

将需要用户实现HandleWindowTermination() - 但我想要有一个可选的实现。

void DefaultHandleWindowTermination() { } // 什么都不做

只有在HandleWindowTermination()从未被定义时才会使用它。

英文:

I maintain rawdraw, and rawdraw uses global symbols to callback, for creation, input, and closure. I would like automatically use one copy of a symbol, say, a no-op if the user has not defined one, or if the user has defined one, I would want to use it.

This isn't a problem for most platforms, but for Android it's incredibly annoying because you can't identify linker issues until the app is running on-device.

The issue is this is in the header. So what I want is a way to, from the same C file, allow a function call to be overridden, but not require it.

I've tried both weak and weak,aliasof(...) attributes and neither seem to allow overriding of a symbol in the same C file.

For example, in this case, a user wants to allow detection of window termination, but many users of this library don't care.

cnfg.h

void HandleWindowTermination();

...

	case APP_CMD_TERM_WINDOW:
              ...
		HandleWindowTermination();
		break;

Would require the user to implement HandleWindowTermination() - but I would like to have an optional implementation of it.

void DefaultHandleWindowTermination() { } // Do nothing

That is only used if HandleWindowTermination() is never defined.

答案1

得分: 4

GCC的"weak"属性并不适用于所有目标。根据GCC手册

此属性需要汇编器和目标文件的支持,可能不适用于所有目标。

因此,您可能需要使用一种解决方法。一种可能的方法是定义一个指向可选实现的函数指针:

   typedef void (* HandleWindowTerminationFuncType) ();
   HandleWindowTerminationFuncType HandleWindowTerminationFunction = NULL;

   static void HandleWindowTermination()
   {
       if(HandleWindowTerminationFunction != NULL)
       {
           HandleWindowTerminationFunction();
       }
       else
       {
           // 默认操作
       }
   }

然后,另一个模块可以实现一个HandleWindowTermination()函数,并将HandleWindowTerminationFunction指针设置为指向该实现(您可以实现一个"setter"函数来执行此操作)。

英文:

GCC "weak" attribute is not available for all targets. From the GCC manual:

> This attribute requires assembler and object file support, and may not be available on all targets.

Hence you may need to use a work-around. One possibility could be to define a function pointer to an optional implementation:

   typedef void (* HandleWindowTerminationFuncType) ();
   HandleWindowTerminationFuncType HandleWindowTerminationFunction = NULL;

   static void HandleWindowTermination()
   {
       if(HandleWindowTerminationFunction != NULL)
       {
           HandleWindowTerminationFunction();
       }
       else
       {
           // Default action
       }
   }

Another module may then implement a HandleWindowTermination() function and set the HandleWindowTerminationFunction pointer to point at that implementation (you may implement a "setter" function to do that).

huangapple
  • 本文由 发表于 2023年6月8日 19:50:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76431571.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定