我有一些返回的C++代码std::function.我想从一些C代码中调用它.这可能吗?作为一个例子,我有以下代码:
typedef std::function<int(int)> AdderFunction;
AdderFunction makeAdder(int amount) {
    return [amount] (int n) {
        return n + amount;
    };
}
extern "C" {
    AdderFunction makeCAdder(int amount) {
        return makeAdder(amount);
    }
}
与clang++ -std=c++11 test.cpp它导致以下警告:
'makeCAdder' has C-linkage specified, but returns user-defined type 'AdderFunction' (aka 'function<int (int)>') which is incompatible with C
我明白为什么会这样,但想知道是否有一种模式可以实现这一目标?
R S*_*ahu 15
C/C++之间最便携的接口方法是使用指针在语言之间传递数据,并使用非成员函数进行函数调用.
.h文件:
#ifdef __cplusplus
extern "C" {
#endif
   // Declare the struct.
   struct Adder;
   // Declare functions to work with the struct.
   Adder* makeAdder(int amount);
   int invokeAdder(Adder* adder, int n);
   void deleteAdder(Adder* adder);
#ifdef __cplusplus
}
#endif
在.cpp文件中实现它们:
#include <functional>
typedef std::function<int(int)> AdderFunction;
struct Adder
{
   AdderFunction f;
};
AdderFunction makeAdderFunction(int amount) {
    return [amount] (int n) {
        return n + amount;
    };
}
Adder* makeAdder(int amount)
{
   Adder* adder = new Adder;
   adder->f = makeAdderFunction(amount);
   return adder;
}
int invokeAdder(Adder* adder, int n)
{
   return adder->f(n);
}
void deleteAdder(Adder* adder)
{
   delete adder;
}
无法std::function从C 调用,因为C不支持所需的语言功能.C没有模板,访问修饰符,可调用对象,虚拟方法或其他任何std::function可以在引擎盖下使用的东西.您需要提出C可以理解的策略.
一种这样的策略是复制/移动std::function到堆并将其作为不透明指针返回.然后,您将通过C++接口提供另一个函数,该函数接受该不透明指针并调用它包含的函数.
// C side
struct function_opaque;
int call_opaque(struct function_opaque*, int param);
// C++ side
extern "C" {
    struct function_opaque {
        std::function<int(int)> f;
    };
    int call_opaque(function_opaque* func, int param) {
        return func->f(param);
    }
};
当然,这会带来内存管理的影响.
extern "C"您需要至少将 typedef 放入块内(以使其编译为 C++)。不过,我不确定这在 C 中是否有效。在 C 中可行的就是使用普通函数指针,例如
extern "C" {
using AdderFunction = int(int);
// old-style: typedef int(*AdderFunction)(int);
}
编辑:如果您使用为您提供std::function对象的 API,则可以使用该std::function::target()方法来获取它引用的(可 C 调用的)原始函数指针。
using AdderFunction = std::function<int(int)>;
extern "C" {
using CAdderFunction = int(int);
CAdderFunction makeCAdder(int amount)
{
        return makeAdder(amount).target<CAdderFunction>();
}
}
| 归档时间: | 
 | 
| 查看次数: | 2755 次 | 
| 最近记录: |