英文:
Weak functions with single-file header libraries
问题
我维护rawdraw,而rawdraw使用全局符号来回调,用于创建、输入和闭包。我想要自动使用一个符号的副本,比如,如果用户没有定义一个符号,或者如果用户定义了一个符号,我想要使用它。
这对大多数平台来说不是问题,但对于Android来说非常烦人,因为在应用程序在设备上运行之前,你无法识别链接器问题。
问题出在头文件中。所以我想要的是一种方式,从同一个C文件中允许函数调用被覆盖,但不要求它。
我尝试过weak
和weak,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).
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论