gpt4 book ai didi

c++ - 使用 C 调用约定调用函数模板特化

转载 作者:IT老高 更新时间:2023-10-28 22:41:32 29 4
gpt4 key购买 nike

我有以下模板

template<typename T> void f(T t) { }

我想将它的特定特化的地址传递给 C 函数

g(&f<int>);

但由于我想要便携,我希望“f”的调用约定与 C 的调用约定相匹配。所以我试验了语言链接如何影响调用约定并发现

  • 函数类型的语言链接会影响调用约定使用
  • 函数名的语言链接会影响修饰

C++ 规范的语言链接部分说

In a linkage-specification, the specified language linkage applies to the function types of all function declarators, function names with external linkage, and variable names with external linkage declared within the linkage-specification.

所以为了防止禁用修饰,模板需要在目标文件中区分不同的特化,我做了如下

extern "C" {
/* function name will not be affected */
template<typename T> static void f(T t) { }
}

但是它给了我一个编译器错误,说模板不能有 C 语言链接,我认为这意味着它提示函数模板的函数类型。事实上,我发现规范要说

A template, a template explicit specialization (14.7.3), and a class template partial specialization shall not have C linkage

现在对我来说很明显我们不想更改 name 的链接,因为我们依赖于 mangling 来工作。但是禁止改变type的链接的原因是什么?它似乎限制了我们必须使用 C++ 调用约定;有人知道原因吗?是否有一种简单的解决方法可以实现我的初始目标?


我改变了我现在尝试只给类型链接的方式,如下

extern "C" typedef void ftype(int);

template<typename T>
ftype f;

这很好用。遗憾的是,在使用这种技术时,我看不到定义 f 的方法。但无论如何,我尝试过的编译器都没有诊断出这一点(尝试过 EDG/comeau、GCC 和 clang),尽管这看起来与以前完全相同:名称应该没有 C 语言链接,但只有类型有。

谁能解释一下?

最佳答案

C header 是什么样的?在某个地方,C 源代码必须枚举允许的回调类型。您应该借此机会拥有一系列宏来生成各个 stub 函数的原型(prototype),并在 C++ 源代码中生成相应的宏序列 extern "C" stub 。


关于第二个问题:是的,这可行,但是 typedef不在模板内。我试图将这样的 typedef 放在一个类中,但结果表明 extern "C" 中甚至不允许使用类模板。 .所以你可以有一个函数模板,但没有依赖类型的参数。

仅定义该函数很容易:

extern "C" typedef void ftype(int);

template<typename T>
static ftype f; // <- added "static" here

template< typename T >
void f(int q) {}

啊哈,可变参数函数!

extern "C" typedef void ftype( int, ... );

template<typename T>
static ftype f;

template< typename T >
static void f( int z, ... ) {
va_list va;
va_start( va, z );
T v = va_arg( va, T );
va_end( va );

std::cout << v;
}

你并不需要类型推导,因为它只是一个回调,所以你可以传递这个 & f<int>对于 C 代码,所有回调都具有相同的类型,它可以在运行时确定类型并通过可变参数传递它想要的任何内容。

关于c++ - 使用 C 调用约定调用函数模板特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5589381/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com