是否允许将指向模板函数的指针传递给 C 库? (作为回调)

Is it allowed to pass a pointer to a template function to C library? (as a callback)

考虑以下代码:

#include <iostream>

struct Foo {
  void work() { std::cout << "foo" << std::endl; }  
};

typedef void function_type(void *arg);

template <typename T>
void function(void *arg)
{
    auto &t = *reinterpret_cast<T*>(arg);
    t.work();
}

void call_function(function_type *fn, void *arg)
{
    fn(arg);
}

int main()
{
    Foo foo;

    call_function(&function<Foo>, &foo);

    return 0;
}

如果 call_function() 是某个 C 库(动态链接到我的程序)的接口,是否可以将指针传递给模板函数的某个特定实例?指向模板函数(实例化)的指针和常规函数之间有什么区别吗?

如图所示代码中,两个函数都有C++语言联动,一切正常。您没有传递模板函数,您传递的是常规函数 从函数模板实例化 .

任何模板一旦被实例化,它就不再是真正的模板了,就像实例化一个 class 给你一个 对象 而不是另一个 class.

虽然缺少一些东西 - 为了链接 C 程序,您需要将接口导入为 extern "C" 将那个链接用于您传递给的任何函数指针它。否则 C 和 C++ 双方可能不同意使用的调用约定,一切都会出错。

由于标准明确规定

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

我们需要一些解决方法。像往常一样,您的 C 回调接受一个参数,因此没有什么可以阻止您在 C 链接蹦床函数中切换调用约定:

extern "C" {
    void bounce(void *arg)
    {
        static_cast<Trampoline *>(arg)->callback();
    }
}

其中 callback 将是一个普通的 C++ 链接函数,包括一个函数模板实例化(或只是一个 std::function 或其他)。