检查函数是否在编译时具有C-linkage [无法解析]

scj*_*nno 8 c++ templates metaprogramming

有没有办法检查extern "C"在编译时是否使用C-linkage(即with )声明给定的函数?

我正在开发一个插件系统.每个插件都可以为插件加载代码提供工厂功能.但是,这必须通过名称(以及随后使用GetProcAddressdlsym)来完成.这要求使用C-linkage声明函数,以防止名称错位.如果使用C++声明引用函数 - 链接(而不是在运行时在具有该名称的函数不存在时查找),则能够抛出编译器错误会很好.

这是我的意思的简化示例:

extern "C" void my_func()
{
}

void my_other_func()
{
}

// Replace this struct with one that actually works
template<typename T>
struct is_c_linkage
{
    static const bool value = true;
};

template<typename T>
void assertCLinkage(T *func)
{
    static_assert(is_c_linkage<T>::value, "Supplied function does not have C-linkage");
}

int main()
{
    assertCLinkage(my_func); // Should compile
    assertCLinkage(my_other_func); // Should NOT compile
}
Run Code Online (Sandbox Code Playgroud)

是否有可能的实现is_c_linkage会为第二个函数抛出编译器错误,但不是第一个?我不确定它是否可能(尽管它可能作为编译器扩展存在,我仍然想知道).谢谢.

Dan*_*ien 2

我同意 Jonathan Leffler 的观点,即以标准方式这可能是不可能的。也许这在某种程度上是可能的,具体取决于编译器甚至编译器的版本,但是您必须进行实验以确定可能的方法并接受编译器的行为可能是无意的并且可能在以后“修复”的事实版本。

\n\n

例如,在 Debian Squeeze 上的 4.4.4 版本中g++,您可能会针对不采用stdcall此方法的函数引发编译器错误:

\n\n
void my_func() __attribute__((stdcall));\nvoid my_func() { }\n\nvoid my_other_func() { }\n\ntemplate <typename ret_, typename... args_>\nstruct stdcall_fun_t\n{\n    typedef ret_ (*type)(args_...) __attribute__((stdcall));\n};\n\nint main()\n{\n    stdcall_fun_t<void>::type pFn(&my_func),\n        pFn2(&my_other_func);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

g++ -std=c++0x无法编译此代码,因为:

\n\n
\n

SO2936360.cpp:17: 错误: 从 \xe2\x80\x98void ( )()\xe2\x80\x99 到 \xe2\x80\x98void ( )()\xe2\x80\x99的无效转换

\n
\n\n

第 17 行是 的声明pFn2。如果我去掉这个声明,那么编译就会成功。

\n\n

不幸的是,该技术不适用于cdecl.

\n